<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
		<id>https://k5wiki.kerberos.org/w/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Ghudson</id>
		<title>K5Wiki - User contributions [en]</title>
		<link rel="self" type="application/atom+xml" href="https://k5wiki.kerberos.org/w/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Ghudson"/>
		<link rel="alternate" type="text/html" href="https://k5wiki.kerberos.org/wiki/Special:Contributions/Ghudson"/>
		<updated>2026-05-13T00:19:18Z</updated>
		<subtitle>User contributions</subtitle>
		<generator>MediaWiki 1.27.4</generator>

	<entry>
		<id>https://k5wiki.kerberos.org/wiki?title=Kerberos_for_Windows_(KfW)_Build_Environment&amp;diff=6066</id>
		<title>Kerberos for Windows (KfW) Build Environment</title>
		<link rel="alternate" type="text/html" href="https://k5wiki.kerberos.org/wiki?title=Kerberos_for_Windows_(KfW)_Build_Environment&amp;diff=6066"/>
				<updated>2026-04-22T21:30:17Z</updated>
		
		<summary type="html">&lt;p&gt;Ghudson: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category: Kerberos for Windows]]&lt;br /&gt;
Directions for producing an environment in which to build&lt;br /&gt;
Kerberos for Windows version 4.2&lt;br /&gt;
&lt;br /&gt;
* Install 64-bit Windows 10.&lt;br /&gt;
&lt;br /&gt;
* Install Visual Studio 2017 Community.&lt;br /&gt;
** Check &amp;quot;Desktop development with C++&amp;quot;.&lt;br /&gt;
** Check &amp;quot;MFC and ATL support&amp;quot;.&lt;br /&gt;
** After installing, locate the Visual Studio 2017 menu under the start menu, and pin the x64 and x86 Native Tools Command Prompt entries to the task bar for e&lt;br /&gt;
&lt;br /&gt;
* Install the chocolatey package manager from https://chocolatey.org/install (by pasting the PowerShell command line into an administrative powershell).  Install the following packages:&lt;br /&gt;
&lt;br /&gt;
  choco install wixtoolset -y&lt;br /&gt;
  choco install strawberryperl -y&lt;br /&gt;
  choco install git -y -params '&amp;quot;/GitAndUnixToolsOnPath&amp;quot;'&lt;br /&gt;
  choco install emacs -y&lt;br /&gt;
  choco install windbg -y&lt;br /&gt;
&lt;br /&gt;
* Add wix to the path.&lt;br /&gt;
** search for &amp;quot;environment&amp;quot; and run &amp;quot;Edit the system environment variables&amp;quot;.&lt;br /&gt;
** Click &amp;quot;environment variables&amp;quot; (button at bottom)&lt;br /&gt;
** click on wix, copy value.&lt;br /&gt;
** click on path, click edit, click new, paste value and add &amp;quot;\bin&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
* Choose a released version of OpenSSL (called X.Y.Z below) and build it:&lt;br /&gt;
&lt;br /&gt;
  cd %homepath%&lt;br /&gt;
  git clone https://github.com/openssl/openssl&lt;br /&gt;
  cd openssl&lt;br /&gt;
  git checkout openssl-X.Y.Z&lt;br /&gt;
  perl Configure&lt;br /&gt;
  nmake&lt;br /&gt;
  nmake install&lt;br /&gt;
  set OPENSSL_DIR=C:\Program Files\OpenSSL&lt;br /&gt;
  set OPENSSL_VERSION=X&lt;br /&gt;
&lt;br /&gt;
* Follow the instructions in src/windows/README to perform a build.  NODEBUG can be set in the environment (&amp;quot;set NODEBUG=1&amp;quot;) to avoid having to specify it on the nmake command line each time.  For MIT-specific builds, also &amp;quot;set MIT_INTERNAL=1&amp;quot; or specify it on the nmake command line when building the installer.&lt;br /&gt;
&lt;br /&gt;
* To sign an MSI file:&lt;br /&gt;
** Connect a cryptographic token with FIPS support containing a code-signing certificate.  If using VMWare Workstation, use VM &amp;gt; Removable Devices to pass through the token, disconnecting it from the host.&lt;br /&gt;
** If it is a Yubikey token containing an ECC code-signing certificate, it may be necessary to install the YubiKey Smart Card Minidriver from https://www.yubico.com/support/download/smart-card-drivers-tools/ .  Reconnect the Yubikey token after installing.&lt;br /&gt;
** Verify that the certificate is visible to Windows using &amp;quot;certutil -store -user my&amp;quot;.&lt;br /&gt;
** Use the command:&lt;br /&gt;
&lt;br /&gt;
  signtool sign /v /d &amp;quot;MIT Kerberos for Windows installer&amp;quot; /a /fd sha256 /tr http://timestamp.comodoca.com /td sha256 kfw.msi&lt;br /&gt;
&lt;br /&gt;
* To obtain a code-signing certificate (these steps are for a Debian-based Linux system):&lt;br /&gt;
** Obtain a cryptographic token with FIPS support.  These notes assume a YubiKey 5 NFC FIPS token.&lt;br /&gt;
** Install the yubikey-manager package.&lt;br /&gt;
** Generate a certificate request and attestation file as follows:&lt;br /&gt;
  ykman piv keys generate -a ECCP384 9a publickey&lt;br /&gt;
    (return to use default key)&lt;br /&gt;
  ykman piv keys attest 9a attest.crt&lt;br /&gt;
  ykman piv certificates request -s &amp;quot;MIT Code Signing&amp;quot; 9a publickey csr&lt;br /&gt;
    (enter default PIN 123456)&lt;br /&gt;
  ykman piv certificates export f9 intermediate.crt&lt;br /&gt;
  cat attest.crt intermediate.crt | base64 &amp;gt; attest.b64&lt;br /&gt;
** Send mail to mitcert@mit.edu .  They will generate an invitation link to cert-manager.com.  When filling out the form, leave the SAN email field blank.  Paste the csr file and the attest.b64 file into the form.&lt;br /&gt;
** After issuance, choose the &amp;quot;Certificate (w/ issuer after), PEM&amp;quot; link from the resulting email message.&lt;br /&gt;
** Import the certificate with &amp;quot;ykman piv certificates import 9a cert.pem&amp;quot; (where &amp;quot;cert.pem&amp;quot; is the downloaded file).&lt;br /&gt;
&lt;br /&gt;
See also https://www.sectigo.com/knowledge-base/detail/Key-Generation-and-Attestation-with-YubiKey .&lt;br /&gt;
&lt;br /&gt;
More general KfW release engineering information at [[Kerberos for Windows Release Engineering]].&lt;/div&gt;</summary>
		<author><name>Ghudson</name></author>	</entry>

	<entry>
		<id>https://k5wiki.kerberos.org/wiki?title=Kerberos_for_Windows_(KfW)_Build_Environment&amp;diff=6065</id>
		<title>Kerberos for Windows (KfW) Build Environment</title>
		<link rel="alternate" type="text/html" href="https://k5wiki.kerberos.org/wiki?title=Kerberos_for_Windows_(KfW)_Build_Environment&amp;diff=6065"/>
				<updated>2026-04-21T21:50:49Z</updated>
		
		<summary type="html">&lt;p&gt;Ghudson: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category: Kerberos for Windows]]&lt;br /&gt;
Directions for producing an environment in which to build&lt;br /&gt;
Kerberos for Windows version 4.2&lt;br /&gt;
&lt;br /&gt;
* Install 64-bit Windows 10.&lt;br /&gt;
&lt;br /&gt;
* Install Visual Studio 2017 Community.&lt;br /&gt;
** Check &amp;quot;Desktop development with C++&amp;quot;.&lt;br /&gt;
** Check &amp;quot;MFC and ATL support&amp;quot;.&lt;br /&gt;
** After installing, locate the Visual Studio 2017 menu under the start menu, and pin the x64 and x86 Native Tools Command Prompt entries to the task bar for e&lt;br /&gt;
&lt;br /&gt;
* Install the chocolatey package manager from https://chocolatey.org/install (by pasting the PowerShell command line into an administrative powershell).  Install the following packages:&lt;br /&gt;
&lt;br /&gt;
  choco install wixtoolset -y&lt;br /&gt;
  choco install strawberryperl -y&lt;br /&gt;
  choco install git -y -params '&amp;quot;/GitAndUnixToolsOnPath&amp;quot;'&lt;br /&gt;
  choco install emacs -y&lt;br /&gt;
  choco install windbg -y&lt;br /&gt;
&lt;br /&gt;
* Add wix to the path.&lt;br /&gt;
** search for &amp;quot;environment&amp;quot; and run &amp;quot;Edit the system environment variables&amp;quot;.&lt;br /&gt;
** Click &amp;quot;environment variables&amp;quot; (button at bottom)&lt;br /&gt;
** click on wix, copy value.&lt;br /&gt;
** click on path, click edit, click new, paste value and add &amp;quot;\bin&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
* Choose a released version of OpenSSL (called X.Y.Z below) and build it:&lt;br /&gt;
&lt;br /&gt;
  cd %homepath%&lt;br /&gt;
  git clone https://github.com/openssl/openssl&lt;br /&gt;
  cd openssl&lt;br /&gt;
  git checkout openssl-X.Y.Z&lt;br /&gt;
  perl Configure&lt;br /&gt;
  nmake&lt;br /&gt;
  nmake install&lt;br /&gt;
  set OPENSSL_DIR=C:\Program Files\OpenSSL&lt;br /&gt;
  set OPENSSL_VERSION=X&lt;br /&gt;
&lt;br /&gt;
Follow the instructions in src/windows/README to perform a build.  NODEBUG can be set in the environment (&amp;quot;set NODEBUG=1&amp;quot;) to avoid having to specify it on the nmake command line each time.  For MIT-specific builds, also &amp;quot;set MIT_INTERNAL=1&amp;quot; or specify it on the nmake command line when building the installer.&lt;br /&gt;
&lt;br /&gt;
Code signing:&lt;br /&gt;
&lt;br /&gt;
    signtool sign /v /d &amp;quot;MIT Kerberos for Windows installer&amp;quot; /a /fd sha256 /tr http://timestamp.comodoca.com /td sha256 foo.msi&lt;br /&gt;
&lt;br /&gt;
See also https://support.comodo.com/index.php?/Default/Knowledgebase/Article/View/68/7/&lt;br /&gt;
&lt;br /&gt;
More general KfW release engineering information at [[Kerberos for Windows Release Engineering]].&lt;/div&gt;</summary>
		<author><name>Ghudson</name></author>	</entry>

	<entry>
		<id>https://k5wiki.kerberos.org/wiki?title=Kerberos_for_Windows_Release_Engineering&amp;diff=6064</id>
		<title>Kerberos for Windows Release Engineering</title>
		<link rel="alternate" type="text/html" href="https://k5wiki.kerberos.org/wiki?title=Kerberos_for_Windows_Release_Engineering&amp;diff=6064"/>
				<updated>2026-04-05T17:41:06Z</updated>
		
		<summary type="html">&lt;p&gt;Ghudson: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category: Kerberos for Windows]]&lt;br /&gt;
Release Engineering notes for the Kerberos for Windows 4.2.0 release&lt;br /&gt;
&lt;br /&gt;
Software to test against new builds:&lt;br /&gt;
* SapGUI&lt;br /&gt;
* OpenAFS&lt;br /&gt;
* SecureCRT (and SecureFX?)&lt;br /&gt;
* SPNEGO (in multiple browsers?)&lt;br /&gt;
* Adobe Keyserver a.k.a the Sassafras key client&lt;br /&gt;
* SMTP/IMAP via Thunderbird (must disable SSPI though?)&lt;br /&gt;
* LDAP in some form?&lt;br /&gt;
* XMPP via, e.g., Pidgin&lt;br /&gt;
&lt;br /&gt;
Upgrades scenarios to test:&lt;br /&gt;
* 32-bit to 32-bit, from 3.2&lt;br /&gt;
* 64-bit to 64-bit, from 3.2&lt;br /&gt;
* 32-bit to 64-bit, from 3.2&lt;br /&gt;
* 32-bit and 64-bit to 64-bit, from 3.2&lt;br /&gt;
* 32-bit to 64-bit, from 4.0&lt;br /&gt;
* 64-bit to 32-bit, from 4.0&lt;br /&gt;
When starting from 3.2, it probably suffices to test the Secure Endpoints versions once only, and assume that there will not be future changes to 4.0 which cause the upgrade process to fail for the SE version but not the MIT-distributed version.&lt;br /&gt;
The NSIS upgrade path is a separate codepath and should be tested separately.&lt;br /&gt;
&lt;br /&gt;
Current known issues:&lt;br /&gt;
* The version number implanted in various dlls no longer reflects the underlying krb5 version (instead using the KfW version); this may not actually be a bug.&lt;br /&gt;
* (Version) upgrades that go from 64-bit to 32-bit leave 64-bit binaries around but otherwise succeed.&lt;br /&gt;
&lt;br /&gt;
See [[Kerberos_for_Windows_(KfW)_Build_Environment]] for notes on setting up the build environment.&lt;br /&gt;
&lt;br /&gt;
Each KfW u.v release line takes place on a krb5-x.y branch.  For instance, KfW 4.2 takes place on the krb5-1.17 branch.  A KfW release tag is kfw-u.v[.w]-{final|betaN}[-mit].  (The WiX installer configuration does not currently have support for alpha versions.)&lt;br /&gt;
&lt;br /&gt;
If the calendar year has changed since the last branch maintenance, pull up the commit updating the project-wide copyright years from the master branch before preparing KfW releases.  Make sure src/windows/version.rc is updated in this commit.&lt;br /&gt;
&lt;br /&gt;
There are two versions of each release, one for MIT-internal use and one for external use.  The MIT-internal version install a short krb5.ini file to set the default realm and a few domain_realm mappings.&lt;br /&gt;
&lt;br /&gt;
Each release has three associated branch commits and two associated tags.  The commits can be produced on Linux, pushed to a private github fork, and checked out on the Windows VM while testing the build process, then pushed to the authoritative repository when basic testing is complete.&lt;br /&gt;
&lt;br /&gt;
* Updates for kfw-u.v[.w]-final-mit (or kfw-u.v[.w]-betaN-mit)&lt;br /&gt;
** In src/patchlevel.h, define KRB5_RELTAIL and KRB5_RELTAG to the tag name (e.g. kfw-u.v-final-mit).  They should have the same value.&lt;br /&gt;
** In src/windows/installer/wix/site-local.wxi, define Beta to the beta number of the release if it is a beta, or comment out the define tag if it is not.  Define VersionMajor, VersionMinor, and VersionPatch to match the intended u.v[.w] version.  If this is the first KfW commit on the krb5-x.y branch, uncomment the definition of Release.&lt;br /&gt;
** In src/windows/kerberos.ver, define KRB5_RELTAIL to &amp;quot;betaN&amp;quot; if this is a beta release.  Change it to &amp;quot;/* #undef KRB5_RELTAIL */&amp;quot; if this is a final release.  Set KRB5_MAJOR_RELEASE, KRB5_MINOR_RELEASE, and KRB5_PATCHLEVEL to match the intended u.v version.  If this is the first KfW commit on the branch, remove the line defining KRB5_RELTAG.&lt;br /&gt;
** In src/windows/winlevel.h, increment KRB5_BUILDLEVEL.  If this is the first KfW commit on the branch, leave it at 0.&lt;br /&gt;
** Tag this commit with the release tag name with the suffix &amp;quot;-mit&amp;quot;.&lt;br /&gt;
** On the master branch, set VersionMajor/VersionMinor in src/windows/installer/wix/site-local.wxi and KRB5_MAJOR_RELEASE/KRB5_MINOR_RELEASE in /src/windows/kerberos.ver to be at least as high as the versions on the branch.&lt;br /&gt;
** Create a source zip achive with &amp;quot;git archive --prefix=&amp;lt;tagname&amp;gt; --format=zip -o /path/to/&amp;lt;tagname&amp;gt;-src.zip &amp;lt;tagname&amp;gt;&amp;quot;.  Sign it with gpg -ab filename.zip to produce the detached .asc signature.&lt;br /&gt;
** Build this release with &amp;quot;set NODEBUG=1&amp;quot; and &amp;quot;set MIT_INTERNAL=1&amp;quot;.&lt;br /&gt;
** Sign the kfw32.msi and kfw64.msi files (see below) and copy them out to be installed with the appropriate names in /mit/kerberos/dist/kfw/u.v.&lt;br /&gt;
&lt;br /&gt;
* Updates for kfw-u.v[.w]-final (or kfw-u.v[.w]-betaN)&lt;br /&gt;
** In src/patchlevel.h, remove the &amp;quot;-mit&amp;quot; from KRB5_RELTAIL and KRB5_RELTAG.  They should still have the same value as each other.&lt;br /&gt;
** In src/windows/winlevel.h, increment KRB5_BUILDLEVEL.&lt;br /&gt;
** Tag this commit with the release tag name without the &amp;quot;-mit&amp;quot; suffix.&lt;br /&gt;
** Build this release with &amp;quot;set NODEBUG=1&amp;quot; but not MIT_INTERNAL.  Sign and copy out the kfw32.msi and kfw64.msi files again.&lt;br /&gt;
&lt;br /&gt;
* Back to krb5-x.y-postrelease&lt;br /&gt;
** In src/patchlevel.h, define KRB5_RELTAIL to &amp;quot;postrelease&amp;quot; and KRB5_RELTAG to &amp;quot;krb5-x.y&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
The code signing command is:&lt;br /&gt;
&lt;br /&gt;
  signtool sign /v /d &amp;quot;MIT Kerberos for Windows installer&amp;quot; /a /fd sha256 /tr http://timestamp.comodoca.com /td sha256 foo.msi&lt;br /&gt;
&lt;br /&gt;
MSI signatures can be verified with &amp;quot;signtool verify /v /pa foo.msi&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
The web page presence for KfW releases is:&lt;br /&gt;
&lt;br /&gt;
* /mit/kerberos/kfw-u.v/kfw-u.v.html&lt;br /&gt;
* /mit/kerberos/kfw-u.v/kfw-u.v/kfw-u.v-help&lt;br /&gt;
* /mit/kerberos/index.html (just the current release link; we haven't written news items since kfw-3.2)&lt;br /&gt;
* /mit/kerberos/dist/historic.html (for old releases)&lt;br /&gt;
* /mit/kerberos/dist/index.html&lt;br /&gt;
* /mit/kerberos/dist/testing.html (for testing releases)&lt;br /&gt;
* /mit/kerberos/dist/kfw/u.v (MSI files, source zip files, signatures)&lt;br /&gt;
&lt;br /&gt;
We used to produce debug symbols during the build, by setting DEBUG_SYMBOL=1 during the build (but not while building the installer) and copying aside the *.pdb files from %KRB_INSTALL_DIR%\bin.  We did not do this for KfW 4.2.&lt;br /&gt;
&lt;br /&gt;
Use the arCHMage package to extract HTML from the CHM file for the web. The tool outputs some bogus absolute URLs for links and inline images, so use&lt;br /&gt;
&lt;br /&gt;
    perl -pi -e 's,((?:href|src)=&amp;quot;)/,\1../,g' */*&lt;br /&gt;
&lt;br /&gt;
to postprocess.&lt;/div&gt;</summary>
		<author><name>Ghudson</name></author>	</entry>

	<entry>
		<id>https://k5wiki.kerberos.org/wiki?title=Buildbot_server_configuration&amp;diff=6063</id>
		<title>Buildbot server configuration</title>
		<link rel="alternate" type="text/html" href="https://k5wiki.kerberos.org/wiki?title=Buildbot_server_configuration&amp;diff=6063"/>
				<updated>2025-07-27T22:40:26Z</updated>
		
		<summary type="html">&lt;p&gt;Ghudson: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page contains notes on the setup of the MIT krb5 buildbot master and workers.  The buildbot master is hosted on krbdev-buildbot.mit.edu.  Workers are listed in machines.txt in the krbdev-services repository.&lt;br /&gt;
&lt;br /&gt;
==Operational notes==&lt;br /&gt;
&lt;br /&gt;
To force a new build on all workers, log into krbdev-buildbot.mit.edu, run &amp;quot;su -s /bin/bash - buildbot&amp;quot;, then run &amp;quot;buildbot sendchange -b master -m localhost:9989 -W yourusername@mit.edu&amp;quot; (or similarly for a different branch).&lt;br /&gt;
&lt;br /&gt;
==Packages==&lt;br /&gt;
&lt;br /&gt;
The python3-buildbot package is required for the buildbot master.  The git package is required for the krb5 repository mirror.&lt;br /&gt;
&lt;br /&gt;
Ubuntu 22.04 does not include the buildbot web interface, so it is necessary to install it using pip3:&lt;br /&gt;
&lt;br /&gt;
  apt install python-pip3&lt;br /&gt;
  pip3 install buildbot-www==3.4.0 buildbot-console-view==3.4.0 buildbot-grid-view==3.4.0 buildbot-waterfall-view==3.4.0&lt;br /&gt;
&lt;br /&gt;
The version &amp;quot;3.4.0&amp;quot; should match the system buildbot package version, which can be determined with &amp;quot;dpkg -l buildbot&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
==buildbot master setup==&lt;br /&gt;
&lt;br /&gt;
Run:&lt;br /&gt;
&lt;br /&gt;
  su -s /bin/bash - buildbot&lt;br /&gt;
  touch .k5login&lt;br /&gt;
  rmdir masters workers&lt;br /&gt;
  buildbot create-master -r master&lt;br /&gt;
&lt;br /&gt;
Install buildbot/master.cfg from krbdev-services into /var/lib/buildbot/master.  Copy /var/lib/buildbot/master/workers.py from the old server.  Make sure both files are owned by and readable by buildbot.  If it is necessary to reconstruct workers.py, has the form:&lt;br /&gt;
&lt;br /&gt;
  from buildbot.worker import Worker&lt;br /&gt;
  workers = [&lt;br /&gt;
      Worker('v09', '&amp;lt;password&amp;gt;', properties={'platform': 'amd64-u1204'}),&lt;br /&gt;
      ...&lt;br /&gt;
  ]&lt;br /&gt;
&lt;br /&gt;
The name and password must match the values used on the worker.  The platform is mostly arbitrary and will be used to construct builder entries.  Multiple workers can have the same platform.  The third argument may be omitted for workers that run special tasks (such as the documentation build) and aren't part of the regular platform builds.&lt;br /&gt;
&lt;br /&gt;
Copy over .ssh/authorized_keys from the old server's /var/lib/buildbot.  If it is necessary to reconstruct it, it must contain the ssh key for each worker entry (.ssh/id_rsa.pub from the buildbot account on the worker).&lt;br /&gt;
&lt;br /&gt;
As root, edit /etc/default/buildmaster and change the values so they read:&lt;br /&gt;
&lt;br /&gt;
  MASTER_ENABLED[1]=1&lt;br /&gt;
  MASTER_NAME[1]=&amp;quot;master&amp;quot;&lt;br /&gt;
  MASTER_USER[1]=&amp;quot;buildbot&amp;quot;&lt;br /&gt;
  MASTER_BASEDIR[1]=&amp;quot;/var/lib/buildbot/master&amp;quot;&lt;br /&gt;
  MASTER_OPTIONS[1]=&amp;quot;&amp;quot;&lt;br /&gt;
  MASTER_PREFIXCMD[1]=&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Run &amp;quot;service buildmaster restart&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Install a krbsnap keytab into /var/lib/buildbot, readable only by root.  Install buildbot/doc-update.sh from krbdev-services into /var/lib/buildbot.  Add the following cron job:&lt;br /&gt;
&lt;br /&gt;
  0 4 * * * /var/lib/buildbot/doc-update.sh&lt;br /&gt;
&lt;br /&gt;
==git mirror setup==&lt;br /&gt;
&lt;br /&gt;
The buildbot master host runs a mirror of the drugstore krb5 git repository, for access by workers and to send change notifications to the buildbot master.&lt;br /&gt;
&lt;br /&gt;
Create a krbsnap account using the uid of the Athena krbsnap user:&lt;br /&gt;
&lt;br /&gt;
  useradd -m -u 38160 -s /bin/bash krbsnap&lt;br /&gt;
&lt;br /&gt;
As krbsnap, create ~/.ssh and add the krbsnap key from /git/krb5.git/hooks/krbsnap_rsa_key.pub on drugstore.mit.edu to ~/.ssh/authorized_keys.  (This file may be managed by ops along with the .k5login file, and ops may have created the krbsnap account during provisioning.)&lt;br /&gt;
&lt;br /&gt;
As krbsnap, run:&lt;br /&gt;
&lt;br /&gt;
  mkdir ~/krb5.git&lt;br /&gt;
  cd ~/krb5.git&lt;br /&gt;
  git init --bare&lt;br /&gt;
&lt;br /&gt;
To populate the git repository, log into drugstore as root, &amp;quot;su -s /bin/bash - yourusername&amp;quot;, and run:&lt;br /&gt;
&lt;br /&gt;
  cd /git/krb5.git&lt;br /&gt;
  GIT_SSH=/git/krb5.git/hooks/ssh-as-krbsnap git push krbsnap&lt;br /&gt;
&lt;br /&gt;
Make sure that /git/krb5.git/config contains a remote named &amp;quot;krbsnap&amp;quot; for krbsnap@krbdev-buildbot.mit.edu, and that the [hooks] section contains an entry &amp;quot;push-to = krbsnap&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
As krbsnap, fetch the git_buildbot.py script ( https://raw.githubusercontent.com/buildbot/buildbot-contrib/master/master/contrib/git_buildbot.py ) into ~/krb5.git/hooks, and modify it to begin with &amp;quot;#!/usr/bin/python3&amp;quot;.  Make sure it is executable.  Run:&lt;br /&gt;
&lt;br /&gt;
  cd ~/krb5.git&lt;br /&gt;
  touch git-daemon-export-ok&lt;br /&gt;
  cd hooks&lt;br /&gt;
  ln -s git_buildbot.py post-receive&lt;br /&gt;
&lt;br /&gt;
As krbsnap, run &amp;quot;crontab -e&amp;quot; and add this entry:&lt;br /&gt;
&lt;br /&gt;
  @reboot git daemon --detach --base-path=$HOME&lt;br /&gt;
&lt;br /&gt;
Run the command by hand to start the daemon initially.&lt;br /&gt;
&lt;br /&gt;
==buildbot worker setup==&lt;br /&gt;
&lt;br /&gt;
For the Solaris buildbot worker, see [[Solaris_Build_Environment]] for platform-specific instructions.&lt;br /&gt;
&lt;br /&gt;
Install the buildbot worker software, using the buildbot-worker package or the platform equivalent.&lt;br /&gt;
&lt;br /&gt;
Install the following Ubuntu packages: autoconf bison build-essential git keyutils ldap-utils libcmocka-dev libkeyutils-dev libldap2-dev liblmdb-dev libresolv-wrapper libsasl2-dev libssl-dev libtool pkg-config python3-kdcproxy python3-pyrad softhsm&lt;br /&gt;
&lt;br /&gt;
Install the slapd package.  apt may ask for a master password twice; the value is unimportant and can be left blank.&lt;br /&gt;
&lt;br /&gt;
On the documentation builder host, install the following packages: doxygen python3-cheetah python3-lxml python3-sphinx.  Also place a copy of /afs/athena.mit.edu/astaff/project/kerberos/mitkc-logo-sm.png in the buildbot home directory (readable by the buildbot user).&lt;br /&gt;
&lt;br /&gt;
If the platform package does not create a buildbot account, create one with a home directory.  Create an empty .k5login file in the buildbot home directory.  These instructions will assume that the buildbot home directory is /var/lib/buildbot.&lt;br /&gt;
&lt;br /&gt;
As the buildbot account (&amp;quot;su -s /bin/bash - buildbot&amp;quot;), generate a key using:&lt;br /&gt;
&lt;br /&gt;
  ssh-keygen -q -N &amp;quot;&amp;quot; -f .ssh/id_rsa -t rsa&lt;br /&gt;
&lt;br /&gt;
Add the contents of .ssh/id_rsa.pub to ~buildbot/.ssh/authorized_keys on krbdev-buildbot.mit.edu.&lt;br /&gt;
&lt;br /&gt;
Run &amp;quot;ssh -l buildbot krbdev-buildbot.mit.edu&amp;quot; to get the master host key into .ssh/known_hosts.  The correct host key fingerprint of the master can be obtained by running &amp;quot;ssh-keygen -l -E sha256 -f /etc/ssh/ssh_host_ecdsa_key.pub&amp;quot; on krbdev-buildbot.mit.edu (or perhaps ssh_host_rsa_key.pub or ssh_host_dsa_key.pub if the worker has an old ssh client).&lt;br /&gt;
&lt;br /&gt;
Create a &amp;quot;workers&amp;quot; directory in buildbot's home directory and run &amp;quot;buildbot-worker create-worker /var/lib/buildbot/workers/NAME 127.0.0.1:9989 NAME PASSWORD&amp;quot;, using the name and password from the workers.py entry for the worker.&lt;br /&gt;
&lt;br /&gt;
Arrange for the buildbot worker process to be started on boot.  On Ubuntu 20.04 and 22.04, this is accomplished by running &amp;quot;systemctl enable buildbot-worker@NAME.service&amp;quot;, which will also start the worker.&lt;br /&gt;
&lt;br /&gt;
Add a cron job for the buildbot account (run &amp;quot;crontab -e&amp;quot; as buildbot) to maintain the ssh tunnel to the master:&lt;br /&gt;
&lt;br /&gt;
  */5 * * * * exec ssh -oExitOnForwardFailure=yes -l buildbot -N -L9989:127.0.0.1:9989 krbdev-buildbot.mit.edu&lt;br /&gt;
&lt;br /&gt;
Run the command manually (backgrounded, without the &amp;quot;exec&amp;quot;) to start it for the current session.&lt;br /&gt;
&lt;br /&gt;
On RHEL workers there are several differences:&lt;br /&gt;
&lt;br /&gt;
* Enable EPEL with the following commands, substituting X with the RHEL version:&lt;br /&gt;
&lt;br /&gt;
  subscription-manager repos --enable codeready-builder-for-rhel-X-$(arch)-rpms&lt;br /&gt;
  dnf -y install https://dl.fedoraproject.org/pub/epel/epel-release-latest-X.noarch.rpm&lt;br /&gt;
&lt;br /&gt;
* Install necessary packages with:&lt;br /&gt;
&lt;br /&gt;
  dnf -y group install &amp;quot;Development Tools&amp;quot;&lt;br /&gt;
  dnf -y install buildbot-worker openldap-devel openldap-clients openldap-servers libcmocka-devel lmdb-devel cyrus-sasl-devel cyrus-sasl-md5 python3-pip keyutils-libs-devel softhsm&lt;br /&gt;
  pip3 install kdcproxy pyrad&lt;br /&gt;
&lt;br /&gt;
* The user account is named buildbot-worker and its homedir is /var/lib/buildbot/worker, so there is no need to create a &amp;quot;workers&amp;quot; subdirectory.  There appear to be no startup scripts, so add a user cron job &amp;quot;@reboot buildbot-worker start $HOME/NAME&amp;quot; to start the worker process on boot.&lt;br /&gt;
&lt;br /&gt;
For the worker running the Coverity scan (it can be co-hosted with a regular builder):&lt;br /&gt;
&lt;br /&gt;
* Download a cov-analysis tarfile from scan.coverity.com.  Untar it in /usr/local and symlink /usr/local/bin/cov-build to ../cov-analysis-[stuff]/bin/cov-build.&lt;br /&gt;
&lt;br /&gt;
* Place the build password in buildbot's $HOME/coverity-password.&lt;br /&gt;
&lt;br /&gt;
* Create and enable a worker named &amp;quot;cov&amp;quot; using the same procedure as described above for regular build workers.&lt;br /&gt;
&lt;br /&gt;
==snapshot service==&lt;br /&gt;
&lt;br /&gt;
This service is probably no longer needed, but the setup details are covered here in case it becomes necessary to resurrect it.&lt;br /&gt;
&lt;br /&gt;
In the krbsnap home directory, create a subdirectory &amp;quot;snap&amp;quot; and copy the krbdev/gensnap script from krbdev-services into it.  Also create a keytab for the krbsnap principal in ~/snap/krbsnap.keytab.  Add the cron job to run gensnap from krbdev/krbsnap-crontab to the crontab for the krbsnap account.  (Do not install sync_gitsvn or its cron job; it is defunct.)&lt;br /&gt;
&lt;br /&gt;
The gensnap script updates a working copy for each branch, runs mkrel, and installs the results in krbsnap@aeneas.mit.edu:/var/ftp/pub/kerberos/dist/vaporware-r-us .  These snapshots are used by the old nightly build infrastructure (scripts in /mit/krbdev/testing), which has been supplanted by other CI systems.&lt;/div&gt;</summary>
		<author><name>Ghudson</name></author>	</entry>

	<entry>
		<id>https://k5wiki.kerberos.org/wiki?title=Buildbot_server_configuration&amp;diff=6062</id>
		<title>Buildbot server configuration</title>
		<link rel="alternate" type="text/html" href="https://k5wiki.kerberos.org/wiki?title=Buildbot_server_configuration&amp;diff=6062"/>
				<updated>2025-07-26T21:34:51Z</updated>
		
		<summary type="html">&lt;p&gt;Ghudson: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page contains notes on the setup of the MIT krb5 buildbot master and workers.  The buildbot master is hosted on krbdev-buildbot.mit.edu.  Workers are listed in machines.txt in the krbdev-services repository.&lt;br /&gt;
&lt;br /&gt;
==Operational notes==&lt;br /&gt;
&lt;br /&gt;
To force a new build on all workers, log into krbdev-buildbot.mit.edu, run &amp;quot;su -s /bin/bash - buildbot&amp;quot;, then run &amp;quot;buildbot sendchange -b master -m localhost:9989 -W yourusername@mit.edu&amp;quot; (or similarly for a different branch).&lt;br /&gt;
&lt;br /&gt;
==Packages==&lt;br /&gt;
&lt;br /&gt;
The python3-buildbot package is required for the buildbot master.  The git package is required for the krb5 repository mirror.&lt;br /&gt;
&lt;br /&gt;
Ubuntu 22.04 does not include the buildbot web interface, so it is necessary to install it using pip3:&lt;br /&gt;
&lt;br /&gt;
  apt install python-pip3&lt;br /&gt;
  pip3 install buildbot-www==3.4.0 buildbot-console-view==3.4.0 buildbot-grid-view==3.4.0 buildbot-waterfall-view==3.4.0&lt;br /&gt;
&lt;br /&gt;
The version &amp;quot;3.4.0&amp;quot; should match the system buildbot package version, which can be determined with &amp;quot;dpkg -l buildbot&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
==buildbot master setup==&lt;br /&gt;
&lt;br /&gt;
Run:&lt;br /&gt;
&lt;br /&gt;
  su -s /bin/bash - buildbot&lt;br /&gt;
  touch .k5login&lt;br /&gt;
  rmdir masters workers&lt;br /&gt;
  buildbot create-master -r master&lt;br /&gt;
&lt;br /&gt;
Install buildbot/master.cfg from krbdev-services into /var/lib/buildbot/master.  Copy /var/lib/buildbot/master/workers.py from the old server.  Make sure both files are owned by and readable by buildbot.  If it is necessary to reconstruct workers.py, has the form:&lt;br /&gt;
&lt;br /&gt;
  from buildbot.worker import Worker&lt;br /&gt;
  workers = [&lt;br /&gt;
      Worker('v09', '&amp;lt;password&amp;gt;', properties={'platform': 'amd64-u1204'}),&lt;br /&gt;
      ...&lt;br /&gt;
  ]&lt;br /&gt;
&lt;br /&gt;
The name and password must match the values used on the worker.  The platform is mostly arbitrary and will be used to construct builder entries.  Multiple workers can have the same platform.  The third argument may be omitted for workers that run special tasks (such as the documentation build) and aren't part of the regular platform builds.&lt;br /&gt;
&lt;br /&gt;
Copy over .ssh/authorized_keys from the old server's /var/lib/buildbot.  If it is necessary to reconstruct it, it must contain the ssh key for each worker entry (.ssh/id_rsa.pub from the buildbot account on the worker).&lt;br /&gt;
&lt;br /&gt;
As root, edit /etc/default/buildmaster and change the values so they read:&lt;br /&gt;
&lt;br /&gt;
  MASTER_ENABLED[1]=1&lt;br /&gt;
  MASTER_NAME[1]=&amp;quot;master&amp;quot;&lt;br /&gt;
  MASTER_USER[1]=&amp;quot;buildbot&amp;quot;&lt;br /&gt;
  MASTER_BASEDIR[1]=&amp;quot;/var/lib/buildbot/master&amp;quot;&lt;br /&gt;
  MASTER_OPTIONS[1]=&amp;quot;&amp;quot;&lt;br /&gt;
  MASTER_PREFIXCMD[1]=&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Run &amp;quot;service buildmaster restart&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Install a krbsnap keytab into /var/lib/buildbot, readable only by root.  Install buildbot/doc-update.sh from krbdev-services into /var/lib/buildbot.  Add the following cron job:&lt;br /&gt;
&lt;br /&gt;
  0 4 * * * /var/lib/buildbot/doc-update.sh&lt;br /&gt;
&lt;br /&gt;
==git mirror setup==&lt;br /&gt;
&lt;br /&gt;
The buildbot master host runs a mirror of the drugstore krb5 git repository, for access by workers and to send change notifications to the buildbot master.&lt;br /&gt;
&lt;br /&gt;
Create a krbsnap account using the uid of the Athena krbsnap user:&lt;br /&gt;
&lt;br /&gt;
  useradd -m -u 38160 -s /bin/bash krbsnap&lt;br /&gt;
&lt;br /&gt;
As krbsnap, create ~/.ssh and add the krbsnap key from /git/krb5.git/hooks/krbsnap_rsa_key.pub on drugstore.mit.edu to ~/.ssh/authorized_keys.  (This file may be managed by ops along with the .k5login file, and ops may have created the krbsnap account during provisioning.)&lt;br /&gt;
&lt;br /&gt;
As krbsnap, run:&lt;br /&gt;
&lt;br /&gt;
  mkdir ~/krb5.git&lt;br /&gt;
  cd ~/krb5.git&lt;br /&gt;
  git init --bare&lt;br /&gt;
&lt;br /&gt;
To populate the git repository, log into drugstore as root, &amp;quot;su -s /bin/bash - yourusername&amp;quot;, and run:&lt;br /&gt;
&lt;br /&gt;
  cd /git/krb5.git&lt;br /&gt;
  GIT_SSH=/git/krb5.git/hooks/ssh-as-krbsnap git push krbsnap&lt;br /&gt;
&lt;br /&gt;
Make sure that /git/krb5.git/config contains a remote named &amp;quot;krbsnap&amp;quot; for krbsnap@krbdev-buildbot.mit.edu, and that the [hooks] section contains an entry &amp;quot;push-to = krbsnap&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
As krbsnap, fetch the git_buildbot.py script ( https://raw.githubusercontent.com/buildbot/buildbot-contrib/master/master/contrib/git_buildbot.py ) into ~/krb5.git/hooks, and modify it to begin with &amp;quot;#!/usr/bin/python3&amp;quot;.  Make sure it is executable.  Run:&lt;br /&gt;
&lt;br /&gt;
  cd ~/krb5.git&lt;br /&gt;
  touch git-daemon-export-ok&lt;br /&gt;
  cd hooks&lt;br /&gt;
  ln -s git_buildbot.py post-receive&lt;br /&gt;
&lt;br /&gt;
As krbsnap, run &amp;quot;crontab -e&amp;quot; and add this entry:&lt;br /&gt;
&lt;br /&gt;
  @reboot git daemon --detach --base-path=$HOME&lt;br /&gt;
&lt;br /&gt;
Run the command by hand to start the daemon initially.&lt;br /&gt;
&lt;br /&gt;
==buildbot worker setup==&lt;br /&gt;
&lt;br /&gt;
For the Solaris buildbot worker, see [[Solaris_Build_Environment]] for platform-specific instructions.&lt;br /&gt;
&lt;br /&gt;
Install the buildbot worker software, using the buildbot-worker package or the platform equivalent.&lt;br /&gt;
&lt;br /&gt;
Install the following Ubuntu packages: autoconf bison build-essential git keyutils ldap-utils libcmocka-dev libkeyutils-dev libldap2-dev liblmdb-dev libresolv-wrapper libsasl2-dev libssl-dev libtool pkg-config python3-kdcproxy python3-pyrad softhsm&lt;br /&gt;
&lt;br /&gt;
Install the slapd package.  apt may ask for a master password twice; the value is unimportant and can be left blank.&lt;br /&gt;
&lt;br /&gt;
On the documentation builder host, install the following packages: doxygen python3-cheetah python3-lxml python3-sphinx.  Also place a copy of /afs/athena.mit.edu/astaff/project/kerberos/mitkc-logo-sm.png in the buildbot home directory (readable by the buildbot user).&lt;br /&gt;
&lt;br /&gt;
If the platform package does not create a buildbot account, create one with a home directory.  Create an empty .k5login file in the buildbot home directory.  These instructions will assume that the buildbot home directory is /var/lib/buildbot.&lt;br /&gt;
&lt;br /&gt;
As the buildbot account (&amp;quot;su -s /bin/bash - buildbot&amp;quot;), generate a key using:&lt;br /&gt;
&lt;br /&gt;
  ssh-keygen -q -N &amp;quot;&amp;quot; -f .ssh/id_rsa -t rsa&lt;br /&gt;
&lt;br /&gt;
Add the contents of .ssh/id_rsa.pub to ~buildbot/.ssh/authorized_keys on krbdev-buildbot.mit.edu.&lt;br /&gt;
&lt;br /&gt;
Run &amp;quot;ssh -l buildbot krbdev-buildbot.mit.edu&amp;quot; to get the master host key into .ssh/known_hosts.  The correct host key fingerprint of the master can be obtained by running &amp;quot;ssh-keygen -l -E sha256 -f /etc/ssh/ssh_host_ecdsa_key.pub&amp;quot; on krbdev-buildbot.mit.edu (or perhaps ssh_host_rsa_key.pub or ssh_host_dsa_key.pub if the worker has an old ssh client).&lt;br /&gt;
&lt;br /&gt;
Create a &amp;quot;workers&amp;quot; directory in buildbot's home directory and run &amp;quot;buildbot-worker create-worker /var/lib/buildbot/workers/NAME 127.0.0.1:9989 NAME PASSWORD&amp;quot;, using the name and password from the workers.py entry for the worker.&lt;br /&gt;
&lt;br /&gt;
Arrange for the buildbot worker process to be started on boot.  On Ubuntu 20.04 and 22.04, this is accomplished by running &amp;quot;systemctl enable buildbot-worker@NAME.service&amp;quot;, which will also start the worker.&lt;br /&gt;
&lt;br /&gt;
Add a cron job for the buildbot account (run &amp;quot;crontab -e&amp;quot; as buildbot) to maintain the ssh tunnel to the master:&lt;br /&gt;
&lt;br /&gt;
  */5 * * * * exec ssh -oExitOnForwardFailure=yes -l buildbot -N -L9989:127.0.0.1:9989 krbdev-buildbot.mit.edu&lt;br /&gt;
&lt;br /&gt;
Run the command manually (backgrounded, without the &amp;quot;exec&amp;quot;) to start it for the current session.&lt;br /&gt;
&lt;br /&gt;
On RHEL workers there are several differences:&lt;br /&gt;
&lt;br /&gt;
* Enable EPEL with the following commands, substituting X with the RHEL version:&lt;br /&gt;
&lt;br /&gt;
  subscription-manager repos --enable codeready-builder-for-rhel-X-$(arch)-rpms&lt;br /&gt;
  dnf -y install https://dl.fedoraproject.org/pub/epel/epel-release-latest-X.noarch.rpm&lt;br /&gt;
&lt;br /&gt;
* Install necessary packages with:&lt;br /&gt;
&lt;br /&gt;
  dnf -y group install &amp;quot;Development Tools&amp;quot;&lt;br /&gt;
  dnf -y install buildbot-worker openldap-devel openldap-clients openldap-servers libcmocka-devel lmdb-devel cyrus-sasl-devel cyrus-sasl-md5 python3-pip keyutils-libs-devel softhsm&lt;br /&gt;
  pip3 install kdcproxy pyrad&lt;br /&gt;
&lt;br /&gt;
* The user account is named buildbot-worker and its homedir is /var/lib/buildbot/worker, so there is no need to create a &amp;quot;workers&amp;quot; subdirectory.  There appear to be no startup scripts, so add a user cron job &amp;quot;@reboot buildbot-worker start $HOME/NAME&amp;quot; to start the worker process on boot.&lt;br /&gt;
&lt;br /&gt;
==snapshot service==&lt;br /&gt;
&lt;br /&gt;
This service is probably no longer needed, but the setup details are covered here in case it becomes necessary to resurrect it.&lt;br /&gt;
&lt;br /&gt;
In the krbsnap home directory, create a subdirectory &amp;quot;snap&amp;quot; and copy the krbdev/gensnap script from krbdev-services into it.  Also create a keytab for the krbsnap principal in ~/snap/krbsnap.keytab.  Add the cron job to run gensnap from krbdev/krbsnap-crontab to the crontab for the krbsnap account.  (Do not install sync_gitsvn or its cron job; it is defunct.)&lt;br /&gt;
&lt;br /&gt;
The gensnap script updates a working copy for each branch, runs mkrel, and installs the results in krbsnap@aeneas.mit.edu:/var/ftp/pub/kerberos/dist/vaporware-r-us .  These snapshots are used by the old nightly build infrastructure (scripts in /mit/krbdev/testing), which has been supplanted by other CI systems.&lt;/div&gt;</summary>
		<author><name>Ghudson</name></author>	</entry>

	<entry>
		<id>https://k5wiki.kerberos.org/wiki?title=Buildbot_server_configuration&amp;diff=6061</id>
		<title>Buildbot server configuration</title>
		<link rel="alternate" type="text/html" href="https://k5wiki.kerberos.org/wiki?title=Buildbot_server_configuration&amp;diff=6061"/>
				<updated>2025-07-26T19:54:30Z</updated>
		
		<summary type="html">&lt;p&gt;Ghudson: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page contains notes on the setup of the MIT krb5 buildbot master and workers.  The buildbot master is hosted on krbdev-buildbot.mit.edu.  Workers are listed in machines.txt in the krbdev-services repository.&lt;br /&gt;
&lt;br /&gt;
==Operational notes==&lt;br /&gt;
&lt;br /&gt;
To force a new build on all workers, log into krbdev-buildbot.mit.edu, run &amp;quot;su -s /bin/bash - buildbot&amp;quot;, then run &amp;quot;buildbot sendchange -b master -m localhost:9989 -W yourusername@mit.edu&amp;quot; (or similarly for a different branch).&lt;br /&gt;
&lt;br /&gt;
==Packages==&lt;br /&gt;
&lt;br /&gt;
The python3-buildbot package is required for the buildbot master.  The git package is required for the krb5 repository mirror.&lt;br /&gt;
&lt;br /&gt;
Ubuntu 22.04 does not include the buildbot web interface, so it is necessary to install it using pip3:&lt;br /&gt;
&lt;br /&gt;
  apt install python-pip3&lt;br /&gt;
  pip3 install buildbot-www==3.4.0 buildbot-console-view==3.4.0 buildbot-grid-view==3.4.0 buildbot-waterfall-view==3.4.0&lt;br /&gt;
&lt;br /&gt;
The version &amp;quot;3.4.0&amp;quot; should match the system buildbot package version, which can be determined with &amp;quot;dpkg -l buildbot&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
==buildbot master setup==&lt;br /&gt;
&lt;br /&gt;
Run:&lt;br /&gt;
&lt;br /&gt;
  su -s /bin/bash - buildbot&lt;br /&gt;
  touch .k5login&lt;br /&gt;
  rmdir masters workers&lt;br /&gt;
  buildbot create-master -r master&lt;br /&gt;
&lt;br /&gt;
Install buildbot/master.cfg from krbdev-services into /var/lib/buildbot/master.  Copy /var/lib/buildbot/master/workers.py from the old server.  Make sure both files are owned by and readable by buildbot.  If it is necessary to reconstruct workers.py, has the form:&lt;br /&gt;
&lt;br /&gt;
  from buildbot.worker import Worker&lt;br /&gt;
  workers = [&lt;br /&gt;
      Worker('v09', '&amp;lt;password&amp;gt;', properties={'platform': 'amd64-u1204'}),&lt;br /&gt;
      ...&lt;br /&gt;
  ]&lt;br /&gt;
&lt;br /&gt;
The name and password must match the values used on the worker.  The platform is mostly arbitrary and will be used to construct builder entries.  Multiple workers can have the same platform.  The third argument may be omitted for workers that run special tasks (such as the documentation build) and aren't part of the regular platform builds.&lt;br /&gt;
&lt;br /&gt;
Copy over .ssh/authorized_keys from the old server's /var/lib/buildbot.  If it is necessary to reconstruct it, it must contain the ssh key for each worker entry (.ssh/id_rsa.pub from the buildbot account on the worker).&lt;br /&gt;
&lt;br /&gt;
As root, edit /etc/default/buildmaster and change the values so they read:&lt;br /&gt;
&lt;br /&gt;
  MASTER_ENABLED[1]=1&lt;br /&gt;
  MASTER_NAME[1]=&amp;quot;master&amp;quot;&lt;br /&gt;
  MASTER_USER[1]=&amp;quot;buildbot&amp;quot;&lt;br /&gt;
  MASTER_BASEDIR[1]=&amp;quot;/var/lib/buildbot/master&amp;quot;&lt;br /&gt;
  MASTER_OPTIONS[1]=&amp;quot;&amp;quot;&lt;br /&gt;
  MASTER_PREFIXCMD[1]=&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Run &amp;quot;service buildmaster restart&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Install a krbsnap keytab into /var/lib/buildbot, readable only by root.  Install buildbot/doc-update.sh from krbdev-services into /var/lib/buildbot.  Add the following cron job:&lt;br /&gt;
&lt;br /&gt;
  0 4 * * * /var/lib/buildbot/doc-update.sh&lt;br /&gt;
&lt;br /&gt;
==git mirror setup==&lt;br /&gt;
&lt;br /&gt;
The buildbot master host runs a mirror of the drugstore krb5 git repository, for access by workers and to send change notifications to the buildbot master.&lt;br /&gt;
&lt;br /&gt;
Create a krbsnap account using the uid of the Athena krbsnap user:&lt;br /&gt;
&lt;br /&gt;
  useradd -m -u 38160 -s /bin/bash krbsnap&lt;br /&gt;
&lt;br /&gt;
As krbsnap, create ~/.ssh and add the krbsnap key from /git/krb5.git/hooks/krbsnap_rsa_key.pub on drugstore.mit.edu to ~/.ssh/authorized_keys.  (This file may be managed by ops along with the .k5login file, and ops may have created the krbsnap account during provisioning.)&lt;br /&gt;
&lt;br /&gt;
As krbsnap, run:&lt;br /&gt;
&lt;br /&gt;
  mkdir ~/krb5.git&lt;br /&gt;
  cd ~/krb5.git&lt;br /&gt;
  git init --bare&lt;br /&gt;
&lt;br /&gt;
To populate the git repository, log into drugstore as root, &amp;quot;su -s /bin/bash - yourusername&amp;quot;, and run:&lt;br /&gt;
&lt;br /&gt;
  cd /git/krb5.git&lt;br /&gt;
  GIT_SSH=/git/krb5.git/hooks/ssh-as-krbsnap git push krbsnap&lt;br /&gt;
&lt;br /&gt;
Make sure that /git/krb5.git/config contains a remote named &amp;quot;krbsnap&amp;quot; for krbsnap@krbdev-buildbot.mit.edu, and that the [hooks] section contains an entry &amp;quot;push-to = krbsnap&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
As krbsnap, fetch the git_buildbot.py script ( https://raw.githubusercontent.com/buildbot/buildbot-contrib/master/master/contrib/git_buildbot.py ) into ~/krb5.git/hooks, and modify it to begin with &amp;quot;#!/usr/bin/python3&amp;quot;.  Make sure it is executable.  Run:&lt;br /&gt;
&lt;br /&gt;
  cd ~/krb5.git&lt;br /&gt;
  touch git-daemon-export-ok&lt;br /&gt;
  cd hooks&lt;br /&gt;
  ln -s git_buildbot.py post-receive&lt;br /&gt;
&lt;br /&gt;
As krbsnap, run &amp;quot;crontab -e&amp;quot; and add this entry:&lt;br /&gt;
&lt;br /&gt;
  @reboot git daemon --detach --base-path=$HOME&lt;br /&gt;
&lt;br /&gt;
Run the command by hand to start the daemon initially.&lt;br /&gt;
&lt;br /&gt;
==buildbot worker setup==&lt;br /&gt;
&lt;br /&gt;
For the Solaris buildbot worker, see [[Solaris_Build_Environment]] for platform-specific instructions.&lt;br /&gt;
&lt;br /&gt;
Install the buildbot worker software, using the buildbot-worker package or the platform equivalent.&lt;br /&gt;
&lt;br /&gt;
Install the following Ubuntu packages: autoconf bison build-essential git keyutils ldap-utils libcmocka-dev libkeyutils-dev libldap2-dev liblmdb-dev libresolv-wrapper libsasl2-dev libssl-dev libtool pkg-config python3-kdcproxy python3-pyrad&lt;br /&gt;
&lt;br /&gt;
Install the slapd package.  apt may ask for a master password twice; the value is unimportant and can be left blank.&lt;br /&gt;
&lt;br /&gt;
On the documentation builder host, install the following packages: doxygen python3-cheetah python3-lxml python3-sphinx.  Also place a copy of /afs/athena.mit.edu/astaff/project/kerberos/mitkc-logo-sm.png in the buildbot home directory (readable by the buildbot user).&lt;br /&gt;
&lt;br /&gt;
If the platform package does not create a buildbot account, create one with a home directory.  Create an empty .k5login file in the buildbot home directory.  These instructions will assume that the buildbot home directory is /var/lib/buildbot.&lt;br /&gt;
&lt;br /&gt;
As the buildbot account (&amp;quot;su -s /bin/bash - buildbot&amp;quot;), generate a key using:&lt;br /&gt;
&lt;br /&gt;
  ssh-keygen -q -N &amp;quot;&amp;quot; -f .ssh/id_rsa -t rsa&lt;br /&gt;
&lt;br /&gt;
Add the contents of .ssh/id_rsa.pub to ~buildbot/.ssh/authorized_keys on krbdev-buildbot.mit.edu.&lt;br /&gt;
&lt;br /&gt;
Run &amp;quot;ssh -l buildbot krbdev-buildbot.mit.edu&amp;quot; to get the master host key into .ssh/known_hosts.  The correct host key fingerprint of the master can be obtained by running &amp;quot;ssh-keygen -l -E sha256 -f /etc/ssh/ssh_host_ecdsa_key.pub&amp;quot; on krbdev-buildbot.mit.edu (or perhaps ssh_host_rsa_key.pub or ssh_host_dsa_key.pub if the worker has an old ssh client).&lt;br /&gt;
&lt;br /&gt;
Create a &amp;quot;workers&amp;quot; directory in buildbot's home directory and run &amp;quot;buildbot-worker create-worker /var/lib/buildbot/workers/NAME 127.0.0.1:9989 NAME PASSWORD&amp;quot;, using the name and password from the workers.py entry for the worker.&lt;br /&gt;
&lt;br /&gt;
Arrange for the buildbot worker process to be started on boot.  On Ubuntu 20.04 and 22.04, this is accomplished by running &amp;quot;systemctl enable buildbot-worker@NAME.service&amp;quot;, which will also start the worker.&lt;br /&gt;
&lt;br /&gt;
Add a cron job for the buildbot account (run &amp;quot;crontab -e&amp;quot; as buildbot) to maintain the ssh tunnel to the master:&lt;br /&gt;
&lt;br /&gt;
  */5 * * * * exec ssh -oExitOnForwardFailure=yes -l buildbot -N -L9989:127.0.0.1:9989 krbdev-buildbot.mit.edu&lt;br /&gt;
&lt;br /&gt;
Run the command manually (backgrounded, without the &amp;quot;exec&amp;quot;) to start it for the current session.&lt;br /&gt;
&lt;br /&gt;
On RHEL workers there are several differences:&lt;br /&gt;
&lt;br /&gt;
* Enable EPEL with the following commands, substituting X with the RHEL version:&lt;br /&gt;
&lt;br /&gt;
  subscription-manager repos --enable codeready-builder-for-rhel-X-$(arch)-rpms&lt;br /&gt;
  dnf -y install https://dl.fedoraproject.org/pub/epel/epel-release-latest-X.noarch.rpm&lt;br /&gt;
&lt;br /&gt;
* Install necessary packages with:&lt;br /&gt;
&lt;br /&gt;
  dnf -y group install &amp;quot;Development Tools&amp;quot;&lt;br /&gt;
  dnf -y install buildbot-worker openldap-devel openldap-clients openldap-servers libcmocka-devel lmdb-devel cyrus-sasl-devel cyrus-sasl-md5 python3-pip&lt;br /&gt;
  pip3 install kdcproxy pyrad&lt;br /&gt;
&lt;br /&gt;
* The user account is named buildbot-worker and its homedir is /var/lib/buildbot/worker, so there is no need to create a &amp;quot;workers&amp;quot; subdirectory.  There appear to be no startup scripts, so add a user cron job &amp;quot;@reboot buildbot-worker start $HOME/NAME&amp;quot; to start the worker process on boot.&lt;br /&gt;
&lt;br /&gt;
==snapshot service==&lt;br /&gt;
&lt;br /&gt;
This service is probably no longer needed, but the setup details are covered here in case it becomes necessary to resurrect it.&lt;br /&gt;
&lt;br /&gt;
In the krbsnap home directory, create a subdirectory &amp;quot;snap&amp;quot; and copy the krbdev/gensnap script from krbdev-services into it.  Also create a keytab for the krbsnap principal in ~/snap/krbsnap.keytab.  Add the cron job to run gensnap from krbdev/krbsnap-crontab to the crontab for the krbsnap account.  (Do not install sync_gitsvn or its cron job; it is defunct.)&lt;br /&gt;
&lt;br /&gt;
The gensnap script updates a working copy for each branch, runs mkrel, and installs the results in krbsnap@aeneas.mit.edu:/var/ftp/pub/kerberos/dist/vaporware-r-us .  These snapshots are used by the old nightly build infrastructure (scripts in /mit/krbdev/testing), which has been supplanted by other CI systems.&lt;/div&gt;</summary>
		<author><name>Ghudson</name></author>	</entry>

	<entry>
		<id>https://k5wiki.kerberos.org/wiki?title=Buildbot_server_configuration&amp;diff=6060</id>
		<title>Buildbot server configuration</title>
		<link rel="alternate" type="text/html" href="https://k5wiki.kerberos.org/wiki?title=Buildbot_server_configuration&amp;diff=6060"/>
				<updated>2025-07-26T19:54:00Z</updated>
		
		<summary type="html">&lt;p&gt;Ghudson: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page contains notes on the setup of the MIT krb5 buildbot master and workers.  The buildbot master is hosted on krbdev-buildbot.mit.edu.  Workers are listed in machines.txt in the krbdev-services repository.&lt;br /&gt;
&lt;br /&gt;
==Operational notes==&lt;br /&gt;
&lt;br /&gt;
To force a new build on all workers, log into krbdev-buildbot.mit.edu, run &amp;quot;su -s /bin/bash - buildbot&amp;quot;, then run &amp;quot;buildbot sendchange -b master -m localhost:9989 -W yourusername@mit.edu&amp;quot; (or similarly for a different branch).&lt;br /&gt;
&lt;br /&gt;
==Packages==&lt;br /&gt;
&lt;br /&gt;
The python3-buildbot package is required for the buildbot master.  The git package is required for the krb5 repository mirror.&lt;br /&gt;
&lt;br /&gt;
Ubuntu 22.04 does not include the buildbot web interface, so it is necessary to install it using pip3:&lt;br /&gt;
&lt;br /&gt;
  apt install python-pip3&lt;br /&gt;
  pip3 install buildbot-www==3.4.0 buildbot-console-view==3.4.0 buildbot-grid-view==3.4.0 buildbot-waterfall-view==3.4.0&lt;br /&gt;
&lt;br /&gt;
The version &amp;quot;3.4.0&amp;quot; should match the system buildbot package version, which can be determined with &amp;quot;dpkg -l buildbot&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
==buildbot master setup==&lt;br /&gt;
&lt;br /&gt;
Run:&lt;br /&gt;
&lt;br /&gt;
  su -s /bin/bash - buildbot&lt;br /&gt;
  touch .k5login&lt;br /&gt;
  rmdir masters workers&lt;br /&gt;
  buildbot create-master -r master&lt;br /&gt;
&lt;br /&gt;
Install buildbot/master.cfg from krbdev-services into /var/lib/buildbot/master.  Copy /var/lib/buildbot/master/workers.py from the old server.  Make sure both files are owned by and readable by buildbot.  If it is necessary to reconstruct workers.py, has the form:&lt;br /&gt;
&lt;br /&gt;
  from buildbot.worker import Worker&lt;br /&gt;
  workers = [&lt;br /&gt;
      Worker('v09', '&amp;lt;password&amp;gt;', properties={'platform': 'amd64-u1204'}),&lt;br /&gt;
      ...&lt;br /&gt;
  ]&lt;br /&gt;
&lt;br /&gt;
The name and password must match the values used on the worker.  The platform is mostly arbitrary and will be used to construct builder entries.  Multiple workers can have the same platform.  The third argument may be omitted for workers that run special tasks (such as the documentation build) and aren't part of the regular platform builds.&lt;br /&gt;
&lt;br /&gt;
Copy over .ssh/authorized_keys from the old server's /var/lib/buildbot.  If it is necessary to reconstruct it, it must contain the ssh key for each worker entry (.ssh/id_rsa.pub from the buildbot account on the worker).&lt;br /&gt;
&lt;br /&gt;
As root, edit /etc/default/buildmaster and change the values so they read:&lt;br /&gt;
&lt;br /&gt;
  MASTER_ENABLED[1]=1&lt;br /&gt;
  MASTER_NAME[1]=&amp;quot;master&amp;quot;&lt;br /&gt;
  MASTER_USER[1]=&amp;quot;buildbot&amp;quot;&lt;br /&gt;
  MASTER_BASEDIR[1]=&amp;quot;/var/lib/buildbot/master&amp;quot;&lt;br /&gt;
  MASTER_OPTIONS[1]=&amp;quot;&amp;quot;&lt;br /&gt;
  MASTER_PREFIXCMD[1]=&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Run &amp;quot;service buildmaster restart&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Install a krbsnap keytab into /var/lib/buildbot, readable only by root.  Install buildbot/doc-update.sh from krbdev-services into /var/lib/buildbot.  Add the following cron job:&lt;br /&gt;
&lt;br /&gt;
  0 4 * * * /var/lib/buildbot/doc-update.sh&lt;br /&gt;
&lt;br /&gt;
==git mirror setup==&lt;br /&gt;
&lt;br /&gt;
The buildbot master host runs a mirror of the drugstore krb5 git repository, for access by workers and to send change notifications to the buildbot master.&lt;br /&gt;
&lt;br /&gt;
Create a krbsnap account using the uid of the Athena krbsnap user:&lt;br /&gt;
&lt;br /&gt;
  useradd -m -u 38160 -s /bin/bash krbsnap&lt;br /&gt;
&lt;br /&gt;
As krbsnap, create ~/.ssh and add the krbsnap key from /git/krb5.git/hooks/krbsnap_rsa_key.pub on drugstore.mit.edu to ~/.ssh/authorized_keys.  (This file may be managed by ops along with the .k5login file, and ops may have created the krbsnap account during provisioning.)&lt;br /&gt;
&lt;br /&gt;
As krbsnap, run:&lt;br /&gt;
&lt;br /&gt;
  mkdir ~/krb5.git&lt;br /&gt;
  cd ~/krb5.git&lt;br /&gt;
  git init --bare&lt;br /&gt;
&lt;br /&gt;
To populate the git repository, log into drugstore as root, &amp;quot;su -s /bin/bash - yourusername&amp;quot;, and run:&lt;br /&gt;
&lt;br /&gt;
  cd /git/krb5.git&lt;br /&gt;
  GIT_SSH=/git/krb5.git/hooks/ssh-as-krbsnap git push krbsnap&lt;br /&gt;
&lt;br /&gt;
Make sure that /git/krb5.git/config contains a remote named &amp;quot;krbsnap&amp;quot; for krbsnap@krbdev-buildbot.mit.edu, and that the [hooks] section contains an entry &amp;quot;push-to = krbsnap&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
As krbsnap, fetch the git_buildbot.py script ( https://raw.githubusercontent.com/buildbot/buildbot-contrib/master/master/contrib/git_buildbot.py ) into ~/krb5.git/hooks, and modify it to begin with &amp;quot;#!/usr/bin/python3&amp;quot;.  Make sure it is executable.  Run:&lt;br /&gt;
&lt;br /&gt;
  cd ~/krb5.git&lt;br /&gt;
  touch git-daemon-export-ok&lt;br /&gt;
  cd hooks&lt;br /&gt;
  ln -s git_buildbot.py post-receive&lt;br /&gt;
&lt;br /&gt;
As krbsnap, run &amp;quot;crontab -e&amp;quot; and add this entry:&lt;br /&gt;
&lt;br /&gt;
  @reboot git daemon --detach --base-path=$HOME&lt;br /&gt;
&lt;br /&gt;
Run the command by hand to start the daemon initially.&lt;br /&gt;
&lt;br /&gt;
==buildbot worker setup==&lt;br /&gt;
&lt;br /&gt;
For the Solaris buildbot worker, see [[Solaris_Build_Environment]] for platform-specific instructions.&lt;br /&gt;
&lt;br /&gt;
Install the buildbot worker software, using the buildbot-worker package or the platform equivalent.&lt;br /&gt;
&lt;br /&gt;
Install the following Ubuntu packages: autoconf bison build-essential git keyutils ldap-utils libcmocka-dev libkeyutils-dev libldap2-dev liblmdb-dev libresolv-wrapper libsasl2-dev libssl-dev libtool pkg-config python3-kdcproxy python3-pyrad&lt;br /&gt;
&lt;br /&gt;
Install the slapd package.  apt may ask for a master password twice; the value is unimportant and can be left blank.&lt;br /&gt;
&lt;br /&gt;
On the documentation builder host, install the following packages: doxygen python3-cheetah python3-lxml python3-sphinx.  Also place a copy of /afs/athena.mit.edu/astaff/project/kerberos/mitkc-logo-sm.png in the buildbot home directory (readable by the buildbot user).&lt;br /&gt;
&lt;br /&gt;
If the platform package does not create a buildbot account, create one with a home directory.  Create an empty .k5login file in the buildbot home directory.  These instructions will assume that the buildbot home directory is /var/lib/buildbot.&lt;br /&gt;
&lt;br /&gt;
As the buildbot account (&amp;quot;su -s /bin/bash - buildbot&amp;quot;), generate a key using:&lt;br /&gt;
&lt;br /&gt;
  ssh-keygen -q -N &amp;quot;&amp;quot; -f .ssh/id_rsa -t rsa&lt;br /&gt;
&lt;br /&gt;
Add the contents of .ssh/id_rsa.pub to ~buildbot/.ssh/authorized_keys on krbdev-buildbot.mit.edu.&lt;br /&gt;
&lt;br /&gt;
Run &amp;quot;ssh -l buildbot krbdev-buildbot.mit.edu&amp;quot; to get the master host key into .ssh/known_hosts.  The correct host key fingerprint of the master can be obtained by running &amp;quot;ssh-keygen -l -E sha256 -f /etc/ssh/ssh_host_ecdsa_key.pub&amp;quot; on krbdev-buildbot.mit.edu (or perhaps ssh_host_rsa_key.pub or ssh_host_dsa_key.pub if the worker has an old ssh client).&lt;br /&gt;
&lt;br /&gt;
Create a &amp;quot;workers&amp;quot; directory in buildbot's home directory and run &amp;quot;buildbot-worker create-worker /var/lib/buildbot/workers/NAME 127.0.0.1:9989 NAME PASSWORD&amp;quot;, using the name and password from the workers.py entry for the worker.&lt;br /&gt;
&lt;br /&gt;
Arrange for the buildbot worker process to be started on boot.  On Ubuntu 20.04 and 22.04, this is accomplished by running &amp;quot;systemctl enable buildbot-worker@NAME.service&amp;quot;, which will also start the worker.&lt;br /&gt;
&lt;br /&gt;
Add a cron job for the buildbot account (run &amp;quot;crontab -e&amp;quot; as buildbot) to maintain the ssh tunnel to the master:&lt;br /&gt;
&lt;br /&gt;
  */5 * * * * exec ssh -oExitOnForwardFailure=yes -l buildbot -N -L9989:127.0.0.1:9989 krbdev-buildbot.mit.edu&lt;br /&gt;
&lt;br /&gt;
Run the command manually (backgrounded, without the &amp;quot;exec&amp;quot;) to start it for the current session.&lt;br /&gt;
&lt;br /&gt;
On RHEL workers there are several differences:&lt;br /&gt;
&lt;br /&gt;
* Enable EPEL with the following commands, substituting X with the RHEL version:&lt;br /&gt;
&lt;br /&gt;
  subscription-manager repos --enable codeready-builder-for-rhel-X-$(arch)-rpms&lt;br /&gt;
  dnf -y install https://dl.fedoraproject.org/pub/epel/epel-release-latest-X.noarch.rpm&lt;br /&gt;
&lt;br /&gt;
* Install necessary packages with:&lt;br /&gt;
&lt;br /&gt;
  dnf -y group install &amp;quot;Development Tools&amp;quot;&lt;br /&gt;
  dnf -y install buildbot-worker openldap-devel openldap-clients openldap-servers libcmocka-devel lmdb-devel cyrus-sasl-devel python3-pip&lt;br /&gt;
  pip3 install kdcproxy pyrad cyrus-sasl-md5&lt;br /&gt;
&lt;br /&gt;
* The user account is named buildbot-worker and its homedir is /var/lib/buildbot/worker, so there is no need to create a &amp;quot;workers&amp;quot; subdirectory.  There appear to be no startup scripts, so add a user cron job &amp;quot;@reboot buildbot-worker start $HOME/NAME&amp;quot; to start the worker process on boot.&lt;br /&gt;
&lt;br /&gt;
==snapshot service==&lt;br /&gt;
&lt;br /&gt;
This service is probably no longer needed, but the setup details are covered here in case it becomes necessary to resurrect it.&lt;br /&gt;
&lt;br /&gt;
In the krbsnap home directory, create a subdirectory &amp;quot;snap&amp;quot; and copy the krbdev/gensnap script from krbdev-services into it.  Also create a keytab for the krbsnap principal in ~/snap/krbsnap.keytab.  Add the cron job to run gensnap from krbdev/krbsnap-crontab to the crontab for the krbsnap account.  (Do not install sync_gitsvn or its cron job; it is defunct.)&lt;br /&gt;
&lt;br /&gt;
The gensnap script updates a working copy for each branch, runs mkrel, and installs the results in krbsnap@aeneas.mit.edu:/var/ftp/pub/kerberos/dist/vaporware-r-us .  These snapshots are used by the old nightly build infrastructure (scripts in /mit/krbdev/testing), which has been supplanted by other CI systems.&lt;/div&gt;</summary>
		<author><name>Ghudson</name></author>	</entry>

	<entry>
		<id>https://k5wiki.kerberos.org/wiki?title=Buildbot_server_configuration&amp;diff=6059</id>
		<title>Buildbot server configuration</title>
		<link rel="alternate" type="text/html" href="https://k5wiki.kerberos.org/wiki?title=Buildbot_server_configuration&amp;diff=6059"/>
				<updated>2025-07-26T05:23:05Z</updated>
		
		<summary type="html">&lt;p&gt;Ghudson: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page contains notes on the setup of the MIT krb5 buildbot master and workers.  The buildbot master is hosted on krbdev-buildbot.mit.edu.  Workers are listed in machines.txt in the krbdev-services repository.&lt;br /&gt;
&lt;br /&gt;
==Operational notes==&lt;br /&gt;
&lt;br /&gt;
To force a new build on all workers, log into krbdev-buildbot.mit.edu, run &amp;quot;su -s /bin/bash - buildbot&amp;quot;, then run &amp;quot;buildbot sendchange -b master -m localhost:9989 -W yourusername@mit.edu&amp;quot; (or similarly for a different branch).&lt;br /&gt;
&lt;br /&gt;
==Packages==&lt;br /&gt;
&lt;br /&gt;
The python3-buildbot package is required for the buildbot master.  The git package is required for the krb5 repository mirror.&lt;br /&gt;
&lt;br /&gt;
Ubuntu 22.04 does not include the buildbot web interface, so it is necessary to install it using pip3:&lt;br /&gt;
&lt;br /&gt;
  apt install python-pip3&lt;br /&gt;
  pip3 install buildbot-www==3.4.0 buildbot-console-view==3.4.0 buildbot-grid-view==3.4.0 buildbot-waterfall-view==3.4.0&lt;br /&gt;
&lt;br /&gt;
The version &amp;quot;3.4.0&amp;quot; should match the system buildbot package version, which can be determined with &amp;quot;dpkg -l buildbot&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
==buildbot master setup==&lt;br /&gt;
&lt;br /&gt;
Run:&lt;br /&gt;
&lt;br /&gt;
  su -s /bin/bash - buildbot&lt;br /&gt;
  touch .k5login&lt;br /&gt;
  rmdir masters workers&lt;br /&gt;
  buildbot create-master -r master&lt;br /&gt;
&lt;br /&gt;
Install buildbot/master.cfg from krbdev-services into /var/lib/buildbot/master.  Copy /var/lib/buildbot/master/workers.py from the old server.  Make sure both files are owned by and readable by buildbot.  If it is necessary to reconstruct workers.py, has the form:&lt;br /&gt;
&lt;br /&gt;
  from buildbot.worker import Worker&lt;br /&gt;
  workers = [&lt;br /&gt;
      Worker('v09', '&amp;lt;password&amp;gt;', properties={'platform': 'amd64-u1204'}),&lt;br /&gt;
      ...&lt;br /&gt;
  ]&lt;br /&gt;
&lt;br /&gt;
The name and password must match the values used on the worker.  The platform is mostly arbitrary and will be used to construct builder entries.  Multiple workers can have the same platform.  The third argument may be omitted for workers that run special tasks (such as the documentation build) and aren't part of the regular platform builds.&lt;br /&gt;
&lt;br /&gt;
Copy over .ssh/authorized_keys from the old server's /var/lib/buildbot.  If it is necessary to reconstruct it, it must contain the ssh key for each worker entry (.ssh/id_rsa.pub from the buildbot account on the worker).&lt;br /&gt;
&lt;br /&gt;
As root, edit /etc/default/buildmaster and change the values so they read:&lt;br /&gt;
&lt;br /&gt;
  MASTER_ENABLED[1]=1&lt;br /&gt;
  MASTER_NAME[1]=&amp;quot;master&amp;quot;&lt;br /&gt;
  MASTER_USER[1]=&amp;quot;buildbot&amp;quot;&lt;br /&gt;
  MASTER_BASEDIR[1]=&amp;quot;/var/lib/buildbot/master&amp;quot;&lt;br /&gt;
  MASTER_OPTIONS[1]=&amp;quot;&amp;quot;&lt;br /&gt;
  MASTER_PREFIXCMD[1]=&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Run &amp;quot;service buildmaster restart&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Install a krbsnap keytab into /var/lib/buildbot, readable only by root.  Install buildbot/doc-update.sh from krbdev-services into /var/lib/buildbot.  Add the following cron job:&lt;br /&gt;
&lt;br /&gt;
  0 4 * * * /var/lib/buildbot/doc-update.sh&lt;br /&gt;
&lt;br /&gt;
==git mirror setup==&lt;br /&gt;
&lt;br /&gt;
The buildbot master host runs a mirror of the drugstore krb5 git repository, for access by workers and to send change notifications to the buildbot master.&lt;br /&gt;
&lt;br /&gt;
Create a krbsnap account using the uid of the Athena krbsnap user:&lt;br /&gt;
&lt;br /&gt;
  useradd -m -u 38160 -s /bin/bash krbsnap&lt;br /&gt;
&lt;br /&gt;
As krbsnap, create ~/.ssh and add the krbsnap key from /git/krb5.git/hooks/krbsnap_rsa_key.pub on drugstore.mit.edu to ~/.ssh/authorized_keys.  (This file may be managed by ops along with the .k5login file, and ops may have created the krbsnap account during provisioning.)&lt;br /&gt;
&lt;br /&gt;
As krbsnap, run:&lt;br /&gt;
&lt;br /&gt;
  mkdir ~/krb5.git&lt;br /&gt;
  cd ~/krb5.git&lt;br /&gt;
  git init --bare&lt;br /&gt;
&lt;br /&gt;
To populate the git repository, log into drugstore as root, &amp;quot;su -s /bin/bash - yourusername&amp;quot;, and run:&lt;br /&gt;
&lt;br /&gt;
  cd /git/krb5.git&lt;br /&gt;
  GIT_SSH=/git/krb5.git/hooks/ssh-as-krbsnap git push krbsnap&lt;br /&gt;
&lt;br /&gt;
Make sure that /git/krb5.git/config contains a remote named &amp;quot;krbsnap&amp;quot; for krbsnap@krbdev-buildbot.mit.edu, and that the [hooks] section contains an entry &amp;quot;push-to = krbsnap&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
As krbsnap, fetch the git_buildbot.py script ( https://raw.githubusercontent.com/buildbot/buildbot-contrib/master/master/contrib/git_buildbot.py ) into ~/krb5.git/hooks, and modify it to begin with &amp;quot;#!/usr/bin/python3&amp;quot;.  Make sure it is executable.  Run:&lt;br /&gt;
&lt;br /&gt;
  cd ~/krb5.git&lt;br /&gt;
  touch git-daemon-export-ok&lt;br /&gt;
  cd hooks&lt;br /&gt;
  ln -s git_buildbot.py post-receive&lt;br /&gt;
&lt;br /&gt;
As krbsnap, run &amp;quot;crontab -e&amp;quot; and add this entry:&lt;br /&gt;
&lt;br /&gt;
  @reboot git daemon --detach --base-path=$HOME&lt;br /&gt;
&lt;br /&gt;
Run the command by hand to start the daemon initially.&lt;br /&gt;
&lt;br /&gt;
==buildbot worker setup==&lt;br /&gt;
&lt;br /&gt;
For the Solaris buildbot worker, see [[Solaris_Build_Environment]] for platform-specific instructions.&lt;br /&gt;
&lt;br /&gt;
Install the buildbot worker software, using the buildbot-worker package or the platform equivalent.&lt;br /&gt;
&lt;br /&gt;
Install the following Ubuntu packages: autoconf bison build-essential git keyutils ldap-utils libcmocka-dev libkeyutils-dev libldap2-dev liblmdb-dev libresolv-wrapper libsasl2-dev libssl-dev libtool pkg-config python3-kdcproxy python3-pyrad&lt;br /&gt;
&lt;br /&gt;
Install the slapd package.  apt may ask for a master password twice; the value is unimportant and can be left blank.&lt;br /&gt;
&lt;br /&gt;
On the documentation builder host, install the following packages: doxygen python3-cheetah python3-lxml python3-sphinx.  Also place a copy of /afs/athena.mit.edu/astaff/project/kerberos/mitkc-logo-sm.png in the buildbot home directory (readable by the buildbot user).&lt;br /&gt;
&lt;br /&gt;
If the platform package does not create a buildbot account, create one with a home directory.  Create an empty .k5login file in the buildbot home directory.  These instructions will assume that the buildbot home directory is /var/lib/buildbot.&lt;br /&gt;
&lt;br /&gt;
As the buildbot account (&amp;quot;su -s /bin/bash - buildbot&amp;quot;), generate a key using:&lt;br /&gt;
&lt;br /&gt;
  ssh-keygen -q -N &amp;quot;&amp;quot; -f .ssh/id_rsa -t rsa&lt;br /&gt;
&lt;br /&gt;
Add the contents of .ssh/id_rsa.pub to ~buildbot/.ssh/authorized_keys on krbdev-buildbot.mit.edu.&lt;br /&gt;
&lt;br /&gt;
Run &amp;quot;ssh -l buildbot krbdev-buildbot.mit.edu&amp;quot; to get the master host key into .ssh/known_hosts.  The correct host key fingerprint of the master can be obtained by running &amp;quot;ssh-keygen -l -E sha256 -f /etc/ssh/ssh_host_ecdsa_key.pub&amp;quot; on krbdev-buildbot.mit.edu (or perhaps ssh_host_rsa_key.pub or ssh_host_dsa_key.pub if the worker has an old ssh client).&lt;br /&gt;
&lt;br /&gt;
Create a &amp;quot;workers&amp;quot; directory in buildbot's home directory and run &amp;quot;buildbot-worker create-worker /var/lib/buildbot/workers/NAME 127.0.0.1:9989 NAME PASSWORD&amp;quot;, using the name and password from the workers.py entry for the worker.&lt;br /&gt;
&lt;br /&gt;
Arrange for the buildbot worker process to be started on boot.  On Ubuntu 20.04 and 22.04, this is accomplished by running &amp;quot;systemctl enable buildbot-worker@NAME.service&amp;quot;, which will also start the worker.&lt;br /&gt;
&lt;br /&gt;
Add a cron job for the buildbot account (run &amp;quot;crontab -e&amp;quot; as buildbot) to maintain the ssh tunnel to the master:&lt;br /&gt;
&lt;br /&gt;
  */5 * * * * exec ssh -oExitOnForwardFailure=yes -l buildbot -N -L9989:127.0.0.1:9989 krbdev-buildbot.mit.edu&lt;br /&gt;
&lt;br /&gt;
Run the command manually (backgrounded, without the &amp;quot;exec&amp;quot;) to start it for the current session.&lt;br /&gt;
&lt;br /&gt;
On RHEL workers there are several differences:&lt;br /&gt;
&lt;br /&gt;
* Enable EPEL with the following commands, substituting X with the RHEL version:&lt;br /&gt;
&lt;br /&gt;
  subscription-manager repos --enable codeready-builder-for-rhel-X-$(arch)-rpms&lt;br /&gt;
  dnf -y install https://dl.fedoraproject.org/pub/epel/epel-release-latest-X.noarch.rpm&lt;br /&gt;
&lt;br /&gt;
* Install necessary packages with:&lt;br /&gt;
&lt;br /&gt;
  dnf -y group install &amp;quot;Development Tools&amp;quot;&lt;br /&gt;
  dnf -y install buildbot-worker openldap-devel openldap-clients openldap-servers libcmocka-devel lmdb-devel cyrus-sasl-devel python3-pip&lt;br /&gt;
  pip3 install kdcproxy pyrad&lt;br /&gt;
&lt;br /&gt;
* The user account is named buildbot-worker and its homedir is /var/lib/buildbot/worker, so there is no need to create a &amp;quot;workers&amp;quot; subdirectory.  There appear to be no startup scripts, so add a user cron job &amp;quot;@reboot buildbot-worker start $HOME/NAME&amp;quot; to start the worker process on boot.&lt;br /&gt;
&lt;br /&gt;
==snapshot service==&lt;br /&gt;
&lt;br /&gt;
This service is probably no longer needed, but the setup details are covered here in case it becomes necessary to resurrect it.&lt;br /&gt;
&lt;br /&gt;
In the krbsnap home directory, create a subdirectory &amp;quot;snap&amp;quot; and copy the krbdev/gensnap script from krbdev-services into it.  Also create a keytab for the krbsnap principal in ~/snap/krbsnap.keytab.  Add the cron job to run gensnap from krbdev/krbsnap-crontab to the crontab for the krbsnap account.  (Do not install sync_gitsvn or its cron job; it is defunct.)&lt;br /&gt;
&lt;br /&gt;
The gensnap script updates a working copy for each branch, runs mkrel, and installs the results in krbsnap@aeneas.mit.edu:/var/ftp/pub/kerberos/dist/vaporware-r-us .  These snapshots are used by the old nightly build infrastructure (scripts in /mit/krbdev/testing), which has been supplanted by other CI systems.&lt;/div&gt;</summary>
		<author><name>Ghudson</name></author>	</entry>

	<entry>
		<id>https://k5wiki.kerberos.org/wiki?title=Buildbot_server_configuration&amp;diff=6058</id>
		<title>Buildbot server configuration</title>
		<link rel="alternate" type="text/html" href="https://k5wiki.kerberos.org/wiki?title=Buildbot_server_configuration&amp;diff=6058"/>
				<updated>2025-07-24T22:53:30Z</updated>
		
		<summary type="html">&lt;p&gt;Ghudson: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page contains notes on the setup of the MIT krb5 buildbot master and workers.  The buildbot master is hosted on krbdev-buildbot.mit.edu.  Workers are listed in machines.txt in the krbdev-services repository.&lt;br /&gt;
&lt;br /&gt;
==Operational notes==&lt;br /&gt;
&lt;br /&gt;
To force a new build on all workers, log into krbdev-buildbot.mit.edu, run &amp;quot;su -s /bin/bash - buildbot&amp;quot;, then run &amp;quot;buildbot sendchange -b master -m localhost:9989 -W yourusername@mit.edu&amp;quot; (or similarly for a different branch).&lt;br /&gt;
&lt;br /&gt;
==Packages==&lt;br /&gt;
&lt;br /&gt;
The python3-buildbot package is required for the buildbot master.  The git package is required for the krb5 repository mirror.&lt;br /&gt;
&lt;br /&gt;
Ubuntu 22.04 does not include the buildbot web interface, so it is necessary to install it using pip3:&lt;br /&gt;
&lt;br /&gt;
  apt install python-pip3&lt;br /&gt;
  pip3 install buildbot-www==3.4.0 buildbot-console-view==3.4.0 buildbot-grid-view==3.4.0 buildbot-waterfall-view==3.4.0&lt;br /&gt;
&lt;br /&gt;
The version &amp;quot;3.4.0&amp;quot; should match the system buildbot package version, which can be determined with &amp;quot;dpkg -l buildbot&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
==buildbot master setup==&lt;br /&gt;
&lt;br /&gt;
Run:&lt;br /&gt;
&lt;br /&gt;
  su -s /bin/bash - buildbot&lt;br /&gt;
  touch .k5login&lt;br /&gt;
  rmdir masters workers&lt;br /&gt;
  buildbot create-master -r master&lt;br /&gt;
&lt;br /&gt;
Install buildbot/master.cfg from krbdev-services into /var/lib/buildbot/master.  Copy /var/lib/buildbot/master/workers.py from the old server.  Make sure both files are owned by and readable by buildbot.  If it is necessary to reconstruct workers.py, has the form:&lt;br /&gt;
&lt;br /&gt;
  from buildbot.worker import Worker&lt;br /&gt;
  workers = [&lt;br /&gt;
      Worker('v09', '&amp;lt;password&amp;gt;', properties={'platform': 'amd64-u1204'}),&lt;br /&gt;
      ...&lt;br /&gt;
  ]&lt;br /&gt;
&lt;br /&gt;
The name and password must match the values used on the worker.  The platform is mostly arbitrary and will be used to construct builder entries.  Multiple workers can have the same platform.  The third argument may be omitted for workers that run special tasks (such as the documentation build) and aren't part of the regular platform builds.&lt;br /&gt;
&lt;br /&gt;
Copy over .ssh/authorized_keys from the old server's /var/lib/buildbot.  If it is necessary to reconstruct it, it must contain the ssh key for each worker entry (.ssh/id_rsa.pub from the buildbot account on the worker).&lt;br /&gt;
&lt;br /&gt;
As root, edit /etc/default/buildmaster and change the values so they read:&lt;br /&gt;
&lt;br /&gt;
  MASTER_ENABLED[1]=1&lt;br /&gt;
  MASTER_NAME[1]=&amp;quot;master&amp;quot;&lt;br /&gt;
  MASTER_USER[1]=&amp;quot;buildbot&amp;quot;&lt;br /&gt;
  MASTER_BASEDIR[1]=&amp;quot;/var/lib/buildbot/master&amp;quot;&lt;br /&gt;
  MASTER_OPTIONS[1]=&amp;quot;&amp;quot;&lt;br /&gt;
  MASTER_PREFIXCMD[1]=&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Run &amp;quot;service buildmaster restart&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Install a krbsnap keytab into /var/lib/buildbot, readable only by root.  Install buildbot/doc-update.sh from krbdev-services into /var/lib/buildbot.  Add the following cron job:&lt;br /&gt;
&lt;br /&gt;
  0 4 * * * /var/lib/buildbot/doc-update.sh&lt;br /&gt;
&lt;br /&gt;
==git mirror setup==&lt;br /&gt;
&lt;br /&gt;
The buildbot master host runs a mirror of the drugstore krb5 git repository, for access by workers and to send change notifications to the buildbot master.&lt;br /&gt;
&lt;br /&gt;
Create a krbsnap account using the uid of the Athena krbsnap user:&lt;br /&gt;
&lt;br /&gt;
  useradd -m -u 38160 -s /bin/bash krbsnap&lt;br /&gt;
&lt;br /&gt;
As krbsnap, create ~/.ssh and add the krbsnap key from /git/krb5.git/hooks/krbsnap_rsa_key.pub on drugstore.mit.edu to ~/.ssh/authorized_keys.  (This file may be managed by ops along with the .k5login file, and ops may have created the krbsnap account during provisioning.)&lt;br /&gt;
&lt;br /&gt;
As krbsnap, run:&lt;br /&gt;
&lt;br /&gt;
  mkdir ~/krb5.git&lt;br /&gt;
  cd ~/krb5.git&lt;br /&gt;
  git init --bare&lt;br /&gt;
&lt;br /&gt;
To populate the git repository, log into drugstore as root, &amp;quot;su -s /bin/bash - yourusername&amp;quot;, and run:&lt;br /&gt;
&lt;br /&gt;
  cd /git/krb5.git&lt;br /&gt;
  GIT_SSH=/git/krb5.git/hooks/ssh-as-krbsnap git push krbsnap&lt;br /&gt;
&lt;br /&gt;
Make sure that /git/krb5.git/config contains a remote named &amp;quot;krbsnap&amp;quot; for krbsnap@krbdev-buildbot.mit.edu, and that the [hooks] section contains an entry &amp;quot;push-to = krbsnap&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
As krbsnap, fetch the git_buildbot.py script ( https://raw.githubusercontent.com/buildbot/buildbot-contrib/master/master/contrib/git_buildbot.py ) into ~/krb5.git/hooks, and modify it to begin with &amp;quot;#!/usr/bin/python3&amp;quot;.  Make sure it is executable.  Run:&lt;br /&gt;
&lt;br /&gt;
  cd ~/krb5.git&lt;br /&gt;
  touch git-daemon-export-ok&lt;br /&gt;
  cd hooks&lt;br /&gt;
  ln -s git_buildbot.py post-receive&lt;br /&gt;
&lt;br /&gt;
As krbsnap, run &amp;quot;crontab -e&amp;quot; and add this entry:&lt;br /&gt;
&lt;br /&gt;
  @reboot git daemon --detach --base-path=$HOME&lt;br /&gt;
&lt;br /&gt;
Run the command by hand to start the daemon initially.&lt;br /&gt;
&lt;br /&gt;
==buildbot worker setup==&lt;br /&gt;
&lt;br /&gt;
For the Solaris buildbot worker, see [[Solaris_Build_Environment]] for platform-specific instructions.&lt;br /&gt;
&lt;br /&gt;
Install the buildbot worker software, using the buildbot-worker package or the platform equivalent.&lt;br /&gt;
&lt;br /&gt;
Install the following Ubuntu packages: autoconf bison build-essential git keyutils ldap-utils libcmocka-dev libkeyutils-dev libldap2-dev liblmdb-dev libresolv-wrapper libsasl2-dev libssl-dev libtool pkg-config python3-kdcproxy python3-pyrad&lt;br /&gt;
&lt;br /&gt;
Install the slapd package.  apt may ask for a master password twice; the value is unimportant and can be left blank.&lt;br /&gt;
&lt;br /&gt;
On the documentation builder host, install the following packages: doxygen python3-cheetah python3-lxml python3-sphinx.  Also place a copy of /afs/athena.mit.edu/astaff/project/kerberos/mitkc-logo-sm.png in the buildbot home directory (readable by the buildbot user).&lt;br /&gt;
&lt;br /&gt;
If the platform package does not create a buildbot account, create one with a home directory.  Create an empty .k5login file in the buildbot home directory.  These instructions will assume that the buildbot home directory is /var/lib/buildbot.&lt;br /&gt;
&lt;br /&gt;
As the buildbot account (&amp;quot;su -s /bin/bash - buildbot&amp;quot;), generate a key using:&lt;br /&gt;
&lt;br /&gt;
  ssh-keygen -q -N &amp;quot;&amp;quot; -f .ssh/id_rsa -t rsa&lt;br /&gt;
&lt;br /&gt;
Add the contents of .ssh/id_rsa.pub to ~buildbot/.ssh/authorized_keys on krbdev-buildbot.mit.edu.&lt;br /&gt;
&lt;br /&gt;
Run &amp;quot;ssh -l buildbot krbdev-buildbot.mit.edu&amp;quot; to get the master host key into .ssh/known_hosts.  The correct host key fingerprint of the master can be obtained by running &amp;quot;ssh-keygen -l -E sha256 -f /etc/ssh/ssh_host_ecdsa_key.pub&amp;quot; on krbdev-buildbot.mit.edu (or perhaps ssh_host_rsa_key.pub or ssh_host_dsa_key.pub if the worker has an old ssh client).&lt;br /&gt;
&lt;br /&gt;
Create a &amp;quot;workers&amp;quot; directory in buildbot's home directory and run &amp;quot;buildbot-worker create-worker /var/lib/buildbot/workers/NAME 127.0.0.1:9989 NAME PASSWORD&amp;quot;, using the name and password from the workers.py entry for the worker.&lt;br /&gt;
&lt;br /&gt;
Arrange for the buildbot worker process to be started on boot.  On Ubuntu 18.04, this is accomplished by editing /etc/default/buildbot-worker as root and setting:&lt;br /&gt;
&lt;br /&gt;
  WORKER_ENABLED[1]=1&lt;br /&gt;
  WORKER_NAME[1]=&amp;quot;NAME&amp;quot;&lt;br /&gt;
  WORKER_USER[1]=&amp;quot;buildbot&amp;quot;&lt;br /&gt;
  WORKER_BASEDIR[1]=&amp;quot;/var/lib/buildbot/workers/NAME&amp;quot;&lt;br /&gt;
  WORKER_OPTIONS[1]=&amp;quot;&amp;quot;&lt;br /&gt;
  WORKER_PREFIXCMD[1]=&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Add a cron job for the buildbot account (run &amp;quot;crontab -e&amp;quot; as buildbot) to maintain the ssh tunnel to the master:&lt;br /&gt;
&lt;br /&gt;
  */5 * * * * exec ssh -oExitOnForwardFailure=yes -l buildbot -N -L9989:127.0.0.1:9989 krbdev-buildbot.mit.edu&lt;br /&gt;
&lt;br /&gt;
Run the command manually (backgrounded, without the &amp;quot;exec&amp;quot;) to start it for the current session.&lt;br /&gt;
&lt;br /&gt;
On RHEL workers there are several differences:&lt;br /&gt;
&lt;br /&gt;
* Enable EPEL with the following commands, substituting X with the RHEL version:&lt;br /&gt;
&lt;br /&gt;
  subscription-manager repos --enable codeready-builder-for-rhel-X-$(arch)-rpms&lt;br /&gt;
  dnf -y install https://dl.fedoraproject.org/pub/epel/epel-release-latest-X.noarch.rpm&lt;br /&gt;
&lt;br /&gt;
* Install necessary packages with:&lt;br /&gt;
&lt;br /&gt;
  dnf -y group install &amp;quot;Development Tools&amp;quot;&lt;br /&gt;
  dnf -y install buildbot-worker openldap-devel openldap-clients openldap-servers libcmocka-devel lmdb-devel cyrus-sasl-devel python3-pip&lt;br /&gt;
  pip3 install kdcproxy pyrad&lt;br /&gt;
&lt;br /&gt;
* The user account is named buildbot-worker and its homedir is /var/lib/buildbot/worker, so there is no need to create a &amp;quot;workers&amp;quot; subdirectory.  There appear to be no startup scripts, so add a user cron job &amp;quot;@reboot buildbot-worker start $HOME/NAME&amp;quot; to start the worker process on boot.&lt;br /&gt;
&lt;br /&gt;
==snapshot service==&lt;br /&gt;
&lt;br /&gt;
This service is probably no longer needed, but the setup details are covered here in case it becomes necessary to resurrect it.&lt;br /&gt;
&lt;br /&gt;
In the krbsnap home directory, create a subdirectory &amp;quot;snap&amp;quot; and copy the krbdev/gensnap script from krbdev-services into it.  Also create a keytab for the krbsnap principal in ~/snap/krbsnap.keytab.  Add the cron job to run gensnap from krbdev/krbsnap-crontab to the crontab for the krbsnap account.  (Do not install sync_gitsvn or its cron job; it is defunct.)&lt;br /&gt;
&lt;br /&gt;
The gensnap script updates a working copy for each branch, runs mkrel, and installs the results in krbsnap@aeneas.mit.edu:/var/ftp/pub/kerberos/dist/vaporware-r-us .  These snapshots are used by the old nightly build infrastructure (scripts in /mit/krbdev/testing), which has been supplanted by other CI systems.&lt;/div&gt;</summary>
		<author><name>Ghudson</name></author>	</entry>

	<entry>
		<id>https://k5wiki.kerberos.org/wiki?title=Buildbot_server_configuration&amp;diff=6057</id>
		<title>Buildbot server configuration</title>
		<link rel="alternate" type="text/html" href="https://k5wiki.kerberos.org/wiki?title=Buildbot_server_configuration&amp;diff=6057"/>
				<updated>2025-07-24T22:05:56Z</updated>
		
		<summary type="html">&lt;p&gt;Ghudson: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page contains notes on the setup of the MIT krb5 buildbot master and workers.  The buildbot master is hosted on krbdev-buildbot.mit.edu.  Workers are listed in machines.txt in the krbdev-services repository.&lt;br /&gt;
&lt;br /&gt;
==Operational notes==&lt;br /&gt;
&lt;br /&gt;
To force a new build on all workers, log into krbdev-buildbot.mit.edu, run &amp;quot;su -s /bin/bash - buildbot&amp;quot;, then run &amp;quot;buildbot sendchange -b master -m localhost:9989 -W yourusername@mit.edu&amp;quot; (or similarly for a different branch).&lt;br /&gt;
&lt;br /&gt;
==Packages==&lt;br /&gt;
&lt;br /&gt;
The python3-buildbot package is required for the buildbot master.  The git package is required for the krb5 repository mirror.&lt;br /&gt;
&lt;br /&gt;
Ubuntu 22.04 does not include the buildbot web interface, so it is necessary to install it using pip3:&lt;br /&gt;
&lt;br /&gt;
  apt install python-pip3&lt;br /&gt;
  pip3 install buildbot-www==3.4.0 buildbot-console-view==3.4.0 buildbot-grid-view==3.4.0 buildbot-waterfall-view==3.4.0&lt;br /&gt;
&lt;br /&gt;
The version &amp;quot;3.4.0&amp;quot; should match the system buildbot package version, which can be determined with &amp;quot;dpkg -l buildbot&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
==buildbot master setup==&lt;br /&gt;
&lt;br /&gt;
Run:&lt;br /&gt;
&lt;br /&gt;
  su -s /bin/bash - buildbot&lt;br /&gt;
  touch .k5login&lt;br /&gt;
  rmdir masters workers&lt;br /&gt;
  buildbot create-master -r master&lt;br /&gt;
&lt;br /&gt;
Install buildbot/master.cfg from krbdev-services into /var/lib/buildbot/master.  Copy /var/lib/buildbot/master/workers.py from the old server.  Make sure both files are owned by and readable by buildbot.  If it is necessary to reconstruct workers.py, has the form:&lt;br /&gt;
&lt;br /&gt;
  from buildbot.worker import Worker&lt;br /&gt;
  workers = [&lt;br /&gt;
      Worker('v09', '&amp;lt;password&amp;gt;', properties={'platform': 'amd64-u1204'}),&lt;br /&gt;
      ...&lt;br /&gt;
  ]&lt;br /&gt;
&lt;br /&gt;
The name and password must match the values used on the worker.  The platform is mostly arbitrary and will be used to construct builder entries.  Multiple workers can have the same platform.  The third argument may be omitted for workers that run special tasks (such as the documentation build) and aren't part of the regular platform builds.&lt;br /&gt;
&lt;br /&gt;
Copy over .ssh/authorized_keys from the old server's /var/lib/buildbot.  If it is necessary to reconstruct it, it must contain the ssh key for each worker entry (.ssh/id_rsa.pub from the buildbot account on the worker).&lt;br /&gt;
&lt;br /&gt;
As root, edit /etc/default/buildmaster and change the values so they read:&lt;br /&gt;
&lt;br /&gt;
  MASTER_ENABLED[1]=1&lt;br /&gt;
  MASTER_NAME[1]=&amp;quot;master&amp;quot;&lt;br /&gt;
  MASTER_USER[1]=&amp;quot;buildbot&amp;quot;&lt;br /&gt;
  MASTER_BASEDIR[1]=&amp;quot;/var/lib/buildbot/master&amp;quot;&lt;br /&gt;
  MASTER_OPTIONS[1]=&amp;quot;&amp;quot;&lt;br /&gt;
  MASTER_PREFIXCMD[1]=&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Run &amp;quot;service buildmaster restart&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Install a krbsnap keytab into /var/lib/buildbot, readable only by root.  Install buildbot/doc-update.sh from krbdev-services into /var/lib/buildbot.  Add the following cron job:&lt;br /&gt;
&lt;br /&gt;
  0 4 * * * /var/lib/buildbot/doc-update.sh&lt;br /&gt;
&lt;br /&gt;
==git mirror setup==&lt;br /&gt;
&lt;br /&gt;
The buildbot master host runs a mirror of the drugstore krb5 git repository, for access by workers and to send change notifications to the buildbot master.&lt;br /&gt;
&lt;br /&gt;
Create a krbsnap account using the uid of the Athena krbsnap user:&lt;br /&gt;
&lt;br /&gt;
  useradd -m -u 38160 -s /bin/bash krbsnap&lt;br /&gt;
&lt;br /&gt;
As krbsnap, create ~/.ssh and add the krbsnap key from /git/krb5.git/hooks/krbsnap_rsa_key.pub on drugstore.mit.edu to ~/.ssh/authorized_keys.  (This file may be managed by ops along with the .k5login file, and ops may have created the krbsnap account during provisioning.)&lt;br /&gt;
&lt;br /&gt;
As krbsnap, run:&lt;br /&gt;
&lt;br /&gt;
  mkdir ~/krb5.git&lt;br /&gt;
  cd ~/krb5.git&lt;br /&gt;
  git init --bare&lt;br /&gt;
&lt;br /&gt;
To populate the git repository, log into drugstore as root, &amp;quot;su -s /bin/bash - yourusername&amp;quot;, and run:&lt;br /&gt;
&lt;br /&gt;
  cd /git/krb5.git&lt;br /&gt;
  GIT_SSH=/git/krb5.git/hooks/ssh-as-krbsnap git push krbsnap&lt;br /&gt;
&lt;br /&gt;
Make sure that /git/krb5.git/config contains a remote named &amp;quot;krbsnap&amp;quot; for krbsnap@krbdev-buildbot.mit.edu, and that the [hooks] section contains an entry &amp;quot;push-to = krbsnap&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
As krbsnap, fetch the git_buildbot.py script ( https://raw.githubusercontent.com/buildbot/buildbot-contrib/master/master/contrib/git_buildbot.py ) into ~/krb5.git/hooks, and modify it to begin with &amp;quot;#!/usr/bin/python3&amp;quot;.  Make sure it is executable.  Run:&lt;br /&gt;
&lt;br /&gt;
  cd ~/krb5.git&lt;br /&gt;
  touch git-daemon-export-ok&lt;br /&gt;
  cd hooks&lt;br /&gt;
  ln -s git_buildbot.py post-receive&lt;br /&gt;
&lt;br /&gt;
As krbsnap, run &amp;quot;crontab -e&amp;quot; and add this entry:&lt;br /&gt;
&lt;br /&gt;
  @reboot git daemon --detach --base-path=$HOME&lt;br /&gt;
&lt;br /&gt;
Run the command by hand to start the daemon initially.&lt;br /&gt;
&lt;br /&gt;
==buildbot worker setup==&lt;br /&gt;
&lt;br /&gt;
For the Solaris buildbot worker, see [[Solaris_Build_Environment]] for platform-specific instructions.&lt;br /&gt;
&lt;br /&gt;
Install the buildbot worker software, using the buildbot-worker package or the platform equivalent.&lt;br /&gt;
&lt;br /&gt;
Install the following Ubuntu packages: autoconf bison build-essential git keyutils ldap-utils libcmocka-dev libkeyutils-dev libldap2-dev liblmdb-dev libresolv-wrapper libsasl2-dev libssl-dev libtool pkg-config python3-kdcproxy python3-pyrad&lt;br /&gt;
&lt;br /&gt;
Install the slapd package.  apt may ask for a master password twice; the value is unimportant and can be left blank.&lt;br /&gt;
&lt;br /&gt;
On the documentation builder, install the following packages: doxygen python3-cheetah python3-lxml python3-sphinx&lt;br /&gt;
&lt;br /&gt;
If the platform package does not create a buildbot account, create one with a home directory.  Create an empty .k5login file in the buildbot home directory.  These instructions will assume that the buildbot home directory is /var/lib/buildbot.&lt;br /&gt;
&lt;br /&gt;
As the buildbot account (&amp;quot;su -s /bin/bash - buildbot&amp;quot;), generate a key using:&lt;br /&gt;
&lt;br /&gt;
  ssh-keygen -q -N &amp;quot;&amp;quot; -f .ssh/id_rsa -t rsa&lt;br /&gt;
&lt;br /&gt;
Add the contents of .ssh/id_rsa.pub to ~buildbot/.ssh/authorized_keys on krbdev-buildbot.mit.edu.&lt;br /&gt;
&lt;br /&gt;
Run &amp;quot;ssh -l buildbot krbdev-buildbot.mit.edu&amp;quot; to get the master host key into .ssh/known_hosts.  The correct host key fingerprint of the master can be obtained by running &amp;quot;ssh-keygen -l -E sha256 -f /etc/ssh/ssh_host_ecdsa_key.pub&amp;quot; on krbdev-buildbot.mit.edu (or perhaps ssh_host_rsa_key.pub or ssh_host_dsa_key.pub if the worker has an old ssh client).&lt;br /&gt;
&lt;br /&gt;
Create a &amp;quot;workers&amp;quot; directory in buildbot's home directory and run &amp;quot;buildbot-worker create-worker /var/lib/buildbot/workers/NAME 127.0.0.1:9989 NAME PASSWORD&amp;quot;, using the name and password from the workers.py entry for the worker.&lt;br /&gt;
&lt;br /&gt;
Arrange for the buildbot worker process to be started on boot.  On Ubuntu 18.04, this is accomplished by editing /etc/default/buildbot-worker as root and setting:&lt;br /&gt;
&lt;br /&gt;
  WORKER_ENABLED[1]=1&lt;br /&gt;
  WORKER_NAME[1]=&amp;quot;NAME&amp;quot;&lt;br /&gt;
  WORKER_USER[1]=&amp;quot;buildbot&amp;quot;&lt;br /&gt;
  WORKER_BASEDIR[1]=&amp;quot;/var/lib/buildbot/workers/NAME&amp;quot;&lt;br /&gt;
  WORKER_OPTIONS[1]=&amp;quot;&amp;quot;&lt;br /&gt;
  WORKER_PREFIXCMD[1]=&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Add a cron job for the buildbot account (run &amp;quot;crontab -e&amp;quot; as buildbot) to maintain the ssh tunnel to the master:&lt;br /&gt;
&lt;br /&gt;
  */5 * * * * exec ssh -oExitOnForwardFailure=yes -l buildbot -N -L9989:127.0.0.1:9989 krbdev-buildbot.mit.edu&lt;br /&gt;
&lt;br /&gt;
Run the command manually (backgrounded, without the &amp;quot;exec&amp;quot;) to start it for the current session.&lt;br /&gt;
&lt;br /&gt;
On RHEL workers there are several differences:&lt;br /&gt;
&lt;br /&gt;
* Enable EPEL with the following commands, substituting X with the RHEL version:&lt;br /&gt;
&lt;br /&gt;
  subscription-manager repos --enable codeready-builder-for-rhel-X-$(arch)-rpms&lt;br /&gt;
  dnf -y install https://dl.fedoraproject.org/pub/epel/epel-release-latest-X.noarch.rpm&lt;br /&gt;
&lt;br /&gt;
* Install necessary packages with:&lt;br /&gt;
&lt;br /&gt;
  dnf -y group install &amp;quot;Development Tools&amp;quot;&lt;br /&gt;
  dnf -y install buildbot-worker openldap-devel openldap-clients openldap-servers libcmocka-devel lmdb-devel cyrus-sasl-devel python3-pip&lt;br /&gt;
  pip3 install kdcproxy pyrad&lt;br /&gt;
&lt;br /&gt;
* The user account is named buildbot-worker and its homedir is /var/lib/buildbot/worker, so there is no need to create a &amp;quot;workers&amp;quot; subdirectory.  There appear to be no startup scripts, so add a user cron job &amp;quot;@reboot buildbot-worker start $HOME/NAME&amp;quot; to start the worker process on boot.&lt;br /&gt;
&lt;br /&gt;
==snapshot service==&lt;br /&gt;
&lt;br /&gt;
This service is probably no longer needed, but the setup details are covered here in case it becomes necessary to resurrect it.&lt;br /&gt;
&lt;br /&gt;
In the krbsnap home directory, create a subdirectory &amp;quot;snap&amp;quot; and copy the krbdev/gensnap script from krbdev-services into it.  Also create a keytab for the krbsnap principal in ~/snap/krbsnap.keytab.  Add the cron job to run gensnap from krbdev/krbsnap-crontab to the crontab for the krbsnap account.  (Do not install sync_gitsvn or its cron job; it is defunct.)&lt;br /&gt;
&lt;br /&gt;
The gensnap script updates a working copy for each branch, runs mkrel, and installs the results in krbsnap@aeneas.mit.edu:/var/ftp/pub/kerberos/dist/vaporware-r-us .  These snapshots are used by the old nightly build infrastructure (scripts in /mit/krbdev/testing), which has been supplanted by other CI systems.&lt;/div&gt;</summary>
		<author><name>Ghudson</name></author>	</entry>

	<entry>
		<id>https://k5wiki.kerberos.org/wiki?title=Buildbot_server_configuration&amp;diff=6056</id>
		<title>Buildbot server configuration</title>
		<link rel="alternate" type="text/html" href="https://k5wiki.kerberos.org/wiki?title=Buildbot_server_configuration&amp;diff=6056"/>
				<updated>2025-07-24T21:56:25Z</updated>
		
		<summary type="html">&lt;p&gt;Ghudson: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page contains notes on the setup of the MIT krb5 buildbot master and workers.  The buildbot master is hosted on krbdev-buildbot.mit.edu.  Workers are listed in machines.txt in the krbdev-services repository.&lt;br /&gt;
&lt;br /&gt;
==Operational notes==&lt;br /&gt;
&lt;br /&gt;
To force a new build on all workers, log into krbdev-buildbot.mit.edu, run &amp;quot;su -s /bin/bash - buildbot&amp;quot;, then run &amp;quot;buildbot sendchange -b master -m localhost:9989 -W yourusername@mit.edu&amp;quot; (or similarly for a different branch).&lt;br /&gt;
&lt;br /&gt;
==Packages==&lt;br /&gt;
&lt;br /&gt;
The python3-buildbot package is required for the buildbot master.  The git package is required for the krb5 repository mirror.&lt;br /&gt;
&lt;br /&gt;
Ubuntu 22.04 does not include the buildbot web interface, so it is necessary to install it using pip3:&lt;br /&gt;
&lt;br /&gt;
  apt install python-pip3&lt;br /&gt;
  pip3 install buildbot-www==3.4.0 buildbot-console-view==3.4.0 buildbot-grid-view==3.4.0 buildbot-waterfall-view==3.4.0&lt;br /&gt;
&lt;br /&gt;
The version &amp;quot;3.4.0&amp;quot; should match the system buildbot package version, which can be determined with &amp;quot;dpkg -l buildbot&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
==buildbot master setup==&lt;br /&gt;
&lt;br /&gt;
Run:&lt;br /&gt;
&lt;br /&gt;
  su -s /bin/bash - buildbot&lt;br /&gt;
  touch .k5login&lt;br /&gt;
  rmdir masters workers&lt;br /&gt;
  buildbot create-master -r master&lt;br /&gt;
&lt;br /&gt;
Install buildbot/master.cfg from krbdev-services into /var/lib/buildbot/master.  Copy /var/lib/buildbot/master/workers.py from the old server.  Make sure both files are owned by and readable by buildbot.  If it is necessary to reconstruct workers.py, has the form:&lt;br /&gt;
&lt;br /&gt;
  from buildbot.worker import Worker&lt;br /&gt;
  workers = [&lt;br /&gt;
      Worker('v09', '&amp;lt;password&amp;gt;', properties={'platform': 'amd64-u1204'}),&lt;br /&gt;
      ...&lt;br /&gt;
  ]&lt;br /&gt;
&lt;br /&gt;
The name and password must match the values used on the worker.  The platform is mostly arbitrary and will be used to construct builder entries.  Multiple workers can have the same platform.  The third argument may be omitted for workers that run special tasks (such as the documentation build) and aren't part of the regular platform builds.&lt;br /&gt;
&lt;br /&gt;
Copy over .ssh/authorized_keys from the old server's /var/lib/buildbot.  If it is necessary to reconstruct it, it must contain the ssh key for each worker entry (.ssh/id_rsa.pub from the buildbot account on the worker).&lt;br /&gt;
&lt;br /&gt;
As root, edit /etc/default/buildmaster and change the values so they read:&lt;br /&gt;
&lt;br /&gt;
  MASTER_ENABLED[1]=1&lt;br /&gt;
  MASTER_NAME[1]=&amp;quot;master&amp;quot;&lt;br /&gt;
  MASTER_USER[1]=&amp;quot;buildbot&amp;quot;&lt;br /&gt;
  MASTER_BASEDIR[1]=&amp;quot;/var/lib/buildbot/master&amp;quot;&lt;br /&gt;
  MASTER_OPTIONS[1]=&amp;quot;&amp;quot;&lt;br /&gt;
  MASTER_PREFIXCMD[1]=&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Run &amp;quot;service buildmaster restart&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Install a krbsnap keytab into /var/lib/buildbot, readable only by root.  Install buildbot/doc-update.sh from krbdev-services into /var/lib/buildbot.  Add the following cron job:&lt;br /&gt;
&lt;br /&gt;
  0 4 * * * /var/lib/buildbot/doc-update.sh&lt;br /&gt;
&lt;br /&gt;
==git mirror setup==&lt;br /&gt;
&lt;br /&gt;
The buildbot master host runs a mirror of the drugstore krb5 git repository, for access by workers and to send change notifications to the buildbot master.&lt;br /&gt;
&lt;br /&gt;
Create a krbsnap account using the uid of the Athena krbsnap user:&lt;br /&gt;
&lt;br /&gt;
  useradd -m -u 38160 -s /bin/bash krbsnap&lt;br /&gt;
&lt;br /&gt;
As krbsnap, create ~/.ssh and add the krbsnap key from /git/krb5.git/hooks/krbsnap_rsa_key.pub on drugstore.mit.edu to ~/.ssh/authorized_keys.  (This file may be managed by ops along with the .k5login file, and ops may have created the krbsnap account during provisioning.)&lt;br /&gt;
&lt;br /&gt;
As krbsnap, run:&lt;br /&gt;
&lt;br /&gt;
  mkdir ~/krb5.git&lt;br /&gt;
  cd ~/krb5.git&lt;br /&gt;
  git init --bare&lt;br /&gt;
&lt;br /&gt;
To populate the git repository, log into drugstore as root, &amp;quot;su -s /bin/bash - yourusername&amp;quot;, and run:&lt;br /&gt;
&lt;br /&gt;
  cd /git/krb5.git&lt;br /&gt;
  GIT_SSH=/git/krb5.git/hooks/ssh-as-krbsnap git push krbsnap&lt;br /&gt;
&lt;br /&gt;
Make sure that /git/krb5.git/config contains a remote named &amp;quot;krbsnap&amp;quot; for krbsnap@krbdev-buildbot.mit.edu, and that the [hooks] section contains an entry &amp;quot;push-to = krbsnap&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
As krbsnap, fetch the git_buildbot.py script ( https://raw.githubusercontent.com/buildbot/buildbot-contrib/master/master/contrib/git_buildbot.py ) into ~/krb5.git/hooks, and modify it to begin with &amp;quot;#!/usr/bin/python3&amp;quot;.  Make sure it is executable.  Run:&lt;br /&gt;
&lt;br /&gt;
  cd ~/krb5.git&lt;br /&gt;
  touch git-daemon-export-ok&lt;br /&gt;
  cd hooks&lt;br /&gt;
  ln -s git_buildbot.py post-receive&lt;br /&gt;
&lt;br /&gt;
As krbsnap, run &amp;quot;crontab -e&amp;quot; and add this entry:&lt;br /&gt;
&lt;br /&gt;
  @reboot git daemon --detach --base-path=$HOME&lt;br /&gt;
&lt;br /&gt;
Run the command by hand to start the daemon initially.&lt;br /&gt;
&lt;br /&gt;
==buildbot worker setup==&lt;br /&gt;
&lt;br /&gt;
For the Solaris buildbot worker, see [[Solaris_Build_Environment]] for platform-specific instructions.&lt;br /&gt;
&lt;br /&gt;
Install the buildbot worker software, using the buildbot-worker package or the platform equivalent.&lt;br /&gt;
&lt;br /&gt;
Install the following Ubuntu packages: autoconf bison build-essential git keyutils ldap-utils libcmocka-dev libkeyutils-dev libldap2-dev liblmdb-dev libresolv-wrapper libsasl2-dev libssl-dev libtool pkg-config python3-kdcproxy python3-pyrad&lt;br /&gt;
&lt;br /&gt;
Install the slapd package.  apt may ask for a master password twice; the value is unimportant and can be left blank.&lt;br /&gt;
&lt;br /&gt;
On the documentation builder, install the following packages: doxygen python3-lxml python3-cheetah&lt;br /&gt;
&lt;br /&gt;
If the platform package does not create a buildbot account, create one with a home directory.  Create an empty .k5login file in the buildbot home directory.  These instructions will assume that the buildbot home directory is /var/lib/buildbot.&lt;br /&gt;
&lt;br /&gt;
As the buildbot account (&amp;quot;su -s /bin/bash - buildbot&amp;quot;), generate a key using:&lt;br /&gt;
&lt;br /&gt;
  ssh-keygen -q -N &amp;quot;&amp;quot; -f .ssh/id_rsa -t rsa&lt;br /&gt;
&lt;br /&gt;
Add the contents of .ssh/id_rsa.pub to ~buildbot/.ssh/authorized_keys on krbdev-buildbot.mit.edu.&lt;br /&gt;
&lt;br /&gt;
Run &amp;quot;ssh -l buildbot krbdev-buildbot.mit.edu&amp;quot; to get the master host key into .ssh/known_hosts.  The correct host key fingerprint of the master can be obtained by running &amp;quot;ssh-keygen -l -E sha256 -f /etc/ssh/ssh_host_ecdsa_key.pub&amp;quot; on krbdev-buildbot.mit.edu (or perhaps ssh_host_rsa_key.pub or ssh_host_dsa_key.pub if the worker has an old ssh client).&lt;br /&gt;
&lt;br /&gt;
Create a &amp;quot;workers&amp;quot; directory in buildbot's home directory and run &amp;quot;buildbot-worker create-worker /var/lib/buildbot/workers/NAME 127.0.0.1:9989 NAME PASSWORD&amp;quot;, using the name and password from the workers.py entry for the worker.&lt;br /&gt;
&lt;br /&gt;
Arrange for the buildbot worker process to be started on boot.  On Ubuntu 18.04, this is accomplished by editing /etc/default/buildbot-worker as root and setting:&lt;br /&gt;
&lt;br /&gt;
  WORKER_ENABLED[1]=1&lt;br /&gt;
  WORKER_NAME[1]=&amp;quot;NAME&amp;quot;&lt;br /&gt;
  WORKER_USER[1]=&amp;quot;buildbot&amp;quot;&lt;br /&gt;
  WORKER_BASEDIR[1]=&amp;quot;/var/lib/buildbot/workers/NAME&amp;quot;&lt;br /&gt;
  WORKER_OPTIONS[1]=&amp;quot;&amp;quot;&lt;br /&gt;
  WORKER_PREFIXCMD[1]=&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Add a cron job for the buildbot account (run &amp;quot;crontab -e&amp;quot; as buildbot) to maintain the ssh tunnel to the master:&lt;br /&gt;
&lt;br /&gt;
  */5 * * * * exec ssh -oExitOnForwardFailure=yes -l buildbot -N -L9989:127.0.0.1:9989 krbdev-buildbot.mit.edu&lt;br /&gt;
&lt;br /&gt;
Run the command manually (backgrounded, without the &amp;quot;exec&amp;quot;) to start it for the current session.&lt;br /&gt;
&lt;br /&gt;
On RHEL workers there are several differences:&lt;br /&gt;
&lt;br /&gt;
* Enable EPEL with the following commands, substituting X with the RHEL version:&lt;br /&gt;
&lt;br /&gt;
  subscription-manager repos --enable codeready-builder-for-rhel-X-$(arch)-rpms&lt;br /&gt;
  dnf -y install https://dl.fedoraproject.org/pub/epel/epel-release-latest-X.noarch.rpm&lt;br /&gt;
&lt;br /&gt;
* Install necessary packages with:&lt;br /&gt;
&lt;br /&gt;
  dnf -y group install &amp;quot;Development Tools&amp;quot;&lt;br /&gt;
  dnf -y install buildbot-worker openldap-devel openldap-clients openldap-servers libcmocka-devel lmdb-devel cyrus-sasl-devel python3-pip&lt;br /&gt;
  pip3 install kdcproxy pyrad&lt;br /&gt;
&lt;br /&gt;
* The user account is named buildbot-worker and its homedir is /var/lib/buildbot/worker, so there is no need to create a &amp;quot;workers&amp;quot; subdirectory.  There appear to be no startup scripts, so add a user cron job &amp;quot;@reboot buildbot-worker start $HOME/NAME&amp;quot; to start the worker process on boot.&lt;br /&gt;
&lt;br /&gt;
==snapshot service==&lt;br /&gt;
&lt;br /&gt;
This service is probably no longer needed, but the setup details are covered here in case it becomes necessary to resurrect it.&lt;br /&gt;
&lt;br /&gt;
In the krbsnap home directory, create a subdirectory &amp;quot;snap&amp;quot; and copy the krbdev/gensnap script from krbdev-services into it.  Also create a keytab for the krbsnap principal in ~/snap/krbsnap.keytab.  Add the cron job to run gensnap from krbdev/krbsnap-crontab to the crontab for the krbsnap account.  (Do not install sync_gitsvn or its cron job; it is defunct.)&lt;br /&gt;
&lt;br /&gt;
The gensnap script updates a working copy for each branch, runs mkrel, and installs the results in krbsnap@aeneas.mit.edu:/var/ftp/pub/kerberos/dist/vaporware-r-us .  These snapshots are used by the old nightly build infrastructure (scripts in /mit/krbdev/testing), which has been supplanted by other CI systems.&lt;/div&gt;</summary>
		<author><name>Ghudson</name></author>	</entry>

	<entry>
		<id>https://k5wiki.kerberos.org/wiki?title=Buildbot_server_configuration&amp;diff=6055</id>
		<title>Buildbot server configuration</title>
		<link rel="alternate" type="text/html" href="https://k5wiki.kerberos.org/wiki?title=Buildbot_server_configuration&amp;diff=6055"/>
				<updated>2025-07-24T18:55:40Z</updated>
		
		<summary type="html">&lt;p&gt;Ghudson: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page contains notes on the setup of the MIT krb5 buildbot master and workers.  The buildbot master is hosted on krbdev-buildbot.mit.edu.  Workers are listed in machines.txt in the krbdev-services repository.&lt;br /&gt;
&lt;br /&gt;
==Operational notes==&lt;br /&gt;
&lt;br /&gt;
To force a new build on all workers, log into krbdev-buildbot.mit.edu, run &amp;quot;su -s /bin/bash - buildbot&amp;quot;, then run &amp;quot;buildbot sendchange -b master -m localhost:9989 -W yourusername@mit.edu&amp;quot; (or similarly for a different branch).&lt;br /&gt;
&lt;br /&gt;
==Packages==&lt;br /&gt;
&lt;br /&gt;
The python3-buildbot package is required for the buildbot master.  The git package is required for the krb5 repository mirror.&lt;br /&gt;
&lt;br /&gt;
Ubuntu 22.04 does not include the buildbot web interface, so it is necessary to install it using pip3:&lt;br /&gt;
&lt;br /&gt;
  apt install python-pip3&lt;br /&gt;
  pip3 install buildbot-www==3.4.0 buildbot-console-view==3.4.0 buildbot-grid-view==3.4.0 buildbot-waterfall-view==3.4.0&lt;br /&gt;
&lt;br /&gt;
The version &amp;quot;3.4.0&amp;quot; should match the system buildbot package version, which can be determined with &amp;quot;dpkg -l buildbot&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
==buildbot master setup==&lt;br /&gt;
&lt;br /&gt;
Run:&lt;br /&gt;
&lt;br /&gt;
  su -s /bin/bash - buildbot&lt;br /&gt;
  touch .k5login&lt;br /&gt;
  rmdir masters workers&lt;br /&gt;
  buildbot create-master -r master&lt;br /&gt;
&lt;br /&gt;
Install buildbot/master.cfg from krbdev-services into /var/lib/buildbot/master.  Copy /var/lib/buildbot/master/workers.py from the old server.  Make sure both files are owned by and readable by buildbot.  If it is necessary to reconstruct workers.py, has the form:&lt;br /&gt;
&lt;br /&gt;
  from buildbot.worker import Worker&lt;br /&gt;
  workers = [&lt;br /&gt;
      Worker('v09', '&amp;lt;password&amp;gt;', properties={'platform': 'amd64-u1204'}),&lt;br /&gt;
      ...&lt;br /&gt;
  ]&lt;br /&gt;
&lt;br /&gt;
The name and password must match the values used on the worker.  The platform is mostly arbitrary and will be used to construct builder entries.  Multiple workers can have the same platform.  The third argument may be omitted for workers that run special tasks (such as the documentation build) and aren't part of the regular platform builds.&lt;br /&gt;
&lt;br /&gt;
Copy over .ssh/authorized_keys from the old server's /var/lib/buildbot.  If it is necessary to reconstruct it, it must contain the ssh key for each worker entry (.ssh/id_rsa.pub from the buildbot account on the worker).&lt;br /&gt;
&lt;br /&gt;
As root, edit /etc/default/buildmaster and change the values so they read:&lt;br /&gt;
&lt;br /&gt;
  MASTER_ENABLED[1]=1&lt;br /&gt;
  MASTER_NAME[1]=&amp;quot;master&amp;quot;&lt;br /&gt;
  MASTER_USER[1]=&amp;quot;buildbot&amp;quot;&lt;br /&gt;
  MASTER_BASEDIR[1]=&amp;quot;/var/lib/buildbot/master&amp;quot;&lt;br /&gt;
  MASTER_OPTIONS[1]=&amp;quot;&amp;quot;&lt;br /&gt;
  MASTER_PREFIXCMD[1]=&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Run &amp;quot;service buildmaster restart&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Install a krbsnap keytab into /var/lib/buildbot, readable only by root.  Install buildbot/doc-update.sh from krbdev-services into /var/lib/buildbot.  Add the following cron job:&lt;br /&gt;
&lt;br /&gt;
  0 4 * * * /var/lib/buildbot/doc-update.sh&lt;br /&gt;
&lt;br /&gt;
==git mirror setup==&lt;br /&gt;
&lt;br /&gt;
The buildbot master host runs a mirror of the drugstore krb5 git repository, for access by workers and to send change notifications to the buildbot master.&lt;br /&gt;
&lt;br /&gt;
Create a krbsnap account using the uid of the Athena krbsnap user:&lt;br /&gt;
&lt;br /&gt;
  useradd -m -u 38160 -s /bin/bash krbsnap&lt;br /&gt;
&lt;br /&gt;
As krbsnap, create ~/.ssh and add the krbsnap key from /git/krb5.git/hooks/krbsnap_rsa_key.pub on drugstore.mit.edu to ~/.ssh/authorized_keys.  (This file may be managed by ops along with the .k5login file, and ops may have created the krbsnap account during provisioning.)&lt;br /&gt;
&lt;br /&gt;
As krbsnap, run:&lt;br /&gt;
&lt;br /&gt;
  mkdir ~/krb5.git&lt;br /&gt;
  cd ~/krb5.git&lt;br /&gt;
  git init --bare&lt;br /&gt;
&lt;br /&gt;
To populate the git repository, log into drugstore as root, &amp;quot;su -s /bin/bash - yourusername&amp;quot;, and run:&lt;br /&gt;
&lt;br /&gt;
  cd /git/krb5.git&lt;br /&gt;
  GIT_SSH=/git/krb5.git/hooks/ssh-as-krbsnap git push krbsnap&lt;br /&gt;
&lt;br /&gt;
Make sure that /git/krb5.git/config contains a remote named &amp;quot;krbsnap&amp;quot; for krbsnap@krbdev-buildbot.mit.edu, and that the [hooks] section contains an entry &amp;quot;push-to = krbsnap&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
As krbsnap, fetch the git_buildbot.py script ( https://raw.githubusercontent.com/buildbot/buildbot-contrib/master/master/contrib/git_buildbot.py ) into ~/krb5.git/hooks, and modify it to begin with &amp;quot;#!/usr/bin/python3&amp;quot;.  Make sure it is executable.  Run:&lt;br /&gt;
&lt;br /&gt;
  cd ~/krb5.git&lt;br /&gt;
  touch git-daemon-export-ok&lt;br /&gt;
  cd hooks&lt;br /&gt;
  ln -s git_buildbot.py post-receive&lt;br /&gt;
&lt;br /&gt;
As krbsnap, run &amp;quot;crontab -e&amp;quot; and add this entry:&lt;br /&gt;
&lt;br /&gt;
  @reboot git daemon --detach --base-path=$HOME&lt;br /&gt;
&lt;br /&gt;
Run the command by hand to start the daemon initially.&lt;br /&gt;
&lt;br /&gt;
==buildbot worker setup==&lt;br /&gt;
&lt;br /&gt;
For the Solaris buildbot worker, see [[Solaris_Build_Environment]] for platform-specific instructions.&lt;br /&gt;
&lt;br /&gt;
Install the buildbot worker software, using the buildbot-worker package or the platform equivalent.&lt;br /&gt;
&lt;br /&gt;
Install the following Ubuntu packages: autoconf bison build-essential git keyutils ldap-utils libcmocka-dev libkeyutils-dev libldap2-dev liblmdb-dev libresolv-wrapper libsasl2-dev libssl-dev libtool pkg-config python3-kdcproxy python3-pyrad&lt;br /&gt;
&lt;br /&gt;
Install the slapd package.  apt may ask for a master password twice; the value is unimportant and can be left blank.&lt;br /&gt;
&lt;br /&gt;
(TBD: enumerate packages needed for documentation build worker.)&lt;br /&gt;
&lt;br /&gt;
If the platform package does not create a buildbot account, create one with a home directory.  Create an empty .k5login file in the buildbot home directory.  These instructions will assume that the buildbot home directory is /var/lib/buildbot.&lt;br /&gt;
&lt;br /&gt;
As the buildbot account (&amp;quot;su -s /bin/bash - buildbot&amp;quot;), generate a key using:&lt;br /&gt;
&lt;br /&gt;
  ssh-keygen -q -N &amp;quot;&amp;quot; -f .ssh/id_rsa -t rsa&lt;br /&gt;
&lt;br /&gt;
Add the contents of .ssh/id_rsa.pub to ~buildbot/.ssh/authorized_keys on krbdev-buildbot.mit.edu.&lt;br /&gt;
&lt;br /&gt;
Run &amp;quot;ssh -l buildbot krbdev-buildbot.mit.edu&amp;quot; to get the master host key into .ssh/known_hosts.  The correct host key fingerprint of the master can be obtained by running &amp;quot;ssh-keygen -l -E sha256 -f /etc/ssh/ssh_host_ecdsa_key.pub&amp;quot; on krbdev-buildbot.mit.edu (or perhaps ssh_host_rsa_key.pub or ssh_host_dsa_key.pub if the worker has an old ssh client).&lt;br /&gt;
&lt;br /&gt;
Create a &amp;quot;workers&amp;quot; directory in buildbot's home directory and run &amp;quot;buildbot-worker create-worker /var/lib/buildbot/workers/NAME 127.0.0.1:9989 NAME PASSWORD&amp;quot;, using the name and password from the workers.py entry for the worker.&lt;br /&gt;
&lt;br /&gt;
Arrange for the buildbot worker process to be started on boot.  On Ubuntu 18.04, this is accomplished by editing /etc/default/buildbot-worker as root and setting:&lt;br /&gt;
&lt;br /&gt;
  WORKER_ENABLED[1]=1&lt;br /&gt;
  WORKER_NAME[1]=&amp;quot;NAME&amp;quot;&lt;br /&gt;
  WORKER_USER[1]=&amp;quot;buildbot&amp;quot;&lt;br /&gt;
  WORKER_BASEDIR[1]=&amp;quot;/var/lib/buildbot/workers/NAME&amp;quot;&lt;br /&gt;
  WORKER_OPTIONS[1]=&amp;quot;&amp;quot;&lt;br /&gt;
  WORKER_PREFIXCMD[1]=&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Add a cron job for the buildbot account (run &amp;quot;crontab -e&amp;quot; as buildbot) to maintain the ssh tunnel to the master:&lt;br /&gt;
&lt;br /&gt;
  */5 * * * * exec ssh -oExitOnForwardFailure=yes -l buildbot -N -L9989:127.0.0.1:9989 krbdev-buildbot.mit.edu&lt;br /&gt;
&lt;br /&gt;
Run the command manually (backgrounded, without the &amp;quot;exec&amp;quot;) to start it for the current session.&lt;br /&gt;
&lt;br /&gt;
The worker which runs the documentation build needs the python3-lxml package, and either the python3-cheetah package (requires Ubuntu 18.10 or higher) or the python3-pip package and &amp;quot;pip3 install cheetah3&amp;quot; to be run.&lt;br /&gt;
&lt;br /&gt;
On RHEL workers there are several differences:&lt;br /&gt;
&lt;br /&gt;
* Enable EPEL with the following commands, substituting X with the RHEL version:&lt;br /&gt;
&lt;br /&gt;
  subscription-manager repos --enable codeready-builder-for-rhel-X-$(arch)-rpms&lt;br /&gt;
  dnf -y install https://dl.fedoraproject.org/pub/epel/epel-release-latest-X.noarch.rpm&lt;br /&gt;
&lt;br /&gt;
* Install necessary packages with:&lt;br /&gt;
&lt;br /&gt;
  dnf -y group install &amp;quot;Development Tools&amp;quot;&lt;br /&gt;
  dnf -y install buildbot-worker openldap-devel openldap-clients openldap-servers libcmocka-devel lmdb-devel cyrus-sasl-devel python3-pip&lt;br /&gt;
  pip3 install kdcproxy pyrad&lt;br /&gt;
&lt;br /&gt;
* The user account is named buildbot-worker and its homedir is /var/lib/buildbot/worker, so there is no need to create a &amp;quot;workers&amp;quot; subdirectory.  There appear to be no startup scripts, so add a user cron job &amp;quot;@reboot buildbot-worker start $HOME/NAME&amp;quot; to start the worker process on boot.&lt;br /&gt;
&lt;br /&gt;
==snapshot service==&lt;br /&gt;
&lt;br /&gt;
This service is probably no longer needed, but the setup details are covered here in case it becomes necessary to resurrect it.&lt;br /&gt;
&lt;br /&gt;
In the krbsnap home directory, create a subdirectory &amp;quot;snap&amp;quot; and copy the krbdev/gensnap script from krbdev-services into it.  Also create a keytab for the krbsnap principal in ~/snap/krbsnap.keytab.  Add the cron job to run gensnap from krbdev/krbsnap-crontab to the crontab for the krbsnap account.  (Do not install sync_gitsvn or its cron job; it is defunct.)&lt;br /&gt;
&lt;br /&gt;
The gensnap script updates a working copy for each branch, runs mkrel, and installs the results in krbsnap@aeneas.mit.edu:/var/ftp/pub/kerberos/dist/vaporware-r-us .  These snapshots are used by the old nightly build infrastructure (scripts in /mit/krbdev/testing), which has been supplanted by other CI systems.&lt;/div&gt;</summary>
		<author><name>Ghudson</name></author>	</entry>

	<entry>
		<id>https://k5wiki.kerberos.org/wiki?title=Buildbot_server_configuration&amp;diff=6054</id>
		<title>Buildbot server configuration</title>
		<link rel="alternate" type="text/html" href="https://k5wiki.kerberos.org/wiki?title=Buildbot_server_configuration&amp;diff=6054"/>
				<updated>2025-07-24T18:52:16Z</updated>
		
		<summary type="html">&lt;p&gt;Ghudson: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page contains notes on the setup of the MIT krb5 buildbot master and workers.  The buildbot master is hosted on krbdev-buildbot.mit.edu.  Workers are listed in machines.txt in the krbdev-services repository.&lt;br /&gt;
&lt;br /&gt;
==Operational notes==&lt;br /&gt;
&lt;br /&gt;
To force a new build on all workers, log into krbdev-buildbot.mit.edu, run &amp;quot;su -s /bin/bash - buildbot&amp;quot;, then run &amp;quot;buildbot sendchange -b master -m localhost:9989 -W yourusername@mit.edu&amp;quot; (or similarly for a different branch).&lt;br /&gt;
&lt;br /&gt;
==Packages==&lt;br /&gt;
&lt;br /&gt;
The python3-buildbot package is required for the buildbot master.  The git package is required for the krb5 repository mirror.&lt;br /&gt;
&lt;br /&gt;
Ubuntu 22.04 does not include the buildbot web interface, so it is necessary to install it using pip3:&lt;br /&gt;
&lt;br /&gt;
  apt install python-pip3&lt;br /&gt;
  pip3 install buildbot-www==3.4.0 buildbot-console-view==3.4.0 buildbot-grid-view==3.4.0 buildbot-waterfall-view==3.4.0&lt;br /&gt;
&lt;br /&gt;
The version &amp;quot;3.4.0&amp;quot; should match the system buildbot package version, which can be determined with &amp;quot;dpkg -l buildbot&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
==buildbot master setup==&lt;br /&gt;
&lt;br /&gt;
Run:&lt;br /&gt;
&lt;br /&gt;
  su -s /bin/bash - buildbot&lt;br /&gt;
  touch .k5login&lt;br /&gt;
  rmdir masters workers&lt;br /&gt;
  buildbot create-master -r master&lt;br /&gt;
&lt;br /&gt;
Install buildbot/master.cfg from krbdev-services into /var/lib/buildbot/master.  Copy /var/lib/buildbot/master/workers.py from the old server.  Make sure both files are owned by and readable by buildbot.  If it is necessary to reconstruct workers.py, has the form:&lt;br /&gt;
&lt;br /&gt;
  from buildbot.worker import Worker&lt;br /&gt;
  workers = [&lt;br /&gt;
      Worker('v09', '&amp;lt;password&amp;gt;', properties={'platform': 'amd64-u1204'}),&lt;br /&gt;
      ...&lt;br /&gt;
  ]&lt;br /&gt;
&lt;br /&gt;
The name and password must match the values used on the worker.  The platform is mostly arbitrary and will be used to construct builder entries.  Multiple workers can have the same platform.  The third argument may be omitted for workers that run special tasks (such as the documentation build) and aren't part of the regular platform builds.&lt;br /&gt;
&lt;br /&gt;
Copy over .ssh/authorized_keys from the old server's /var/lib/buildbot.  If it is necessary to reconstruct it, it must contain the ssh key for each worker entry (.ssh/id_rsa.pub from the buildbot account on the worker).&lt;br /&gt;
&lt;br /&gt;
As root, edit /etc/default/buildmaster and change the values so they read:&lt;br /&gt;
&lt;br /&gt;
  MASTER_ENABLED[1]=1&lt;br /&gt;
  MASTER_NAME[1]=&amp;quot;master&amp;quot;&lt;br /&gt;
  MASTER_USER[1]=&amp;quot;buildbot&amp;quot;&lt;br /&gt;
  MASTER_BASEDIR[1]=&amp;quot;/var/lib/buildbot/master&amp;quot;&lt;br /&gt;
  MASTER_OPTIONS[1]=&amp;quot;&amp;quot;&lt;br /&gt;
  MASTER_PREFIXCMD[1]=&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Run &amp;quot;service buildmaster restart&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Install a krbsnap keytab into /var/lib/buildbot, readable only by root.  Install buildbot/doc-update.sh from krbdev-services into /var/lib/buildbot.  Add the following cron job:&lt;br /&gt;
&lt;br /&gt;
  0 4 * * * /var/lib/buildbot/doc-update.sh&lt;br /&gt;
&lt;br /&gt;
==git mirror setup==&lt;br /&gt;
&lt;br /&gt;
The buildbot master host runs a mirror of the drugstore krb5 git repository, for access by workers and to send change notifications to the buildbot master.&lt;br /&gt;
&lt;br /&gt;
Create a krbsnap account using the uid of the Athena krbsnap user:&lt;br /&gt;
&lt;br /&gt;
  useradd -m -u 38160 -s /bin/bash krbsnap&lt;br /&gt;
&lt;br /&gt;
As krbsnap, create ~/.ssh and add the krbsnap key from /git/krb5.git/hooks/krbsnap_rsa_key.pub on drugstore.mit.edu to ~/.ssh/authorized_keys.  (This file may be managed by ops along with the .k5login file, and ops may have created the krbsnap account during provisioning.)&lt;br /&gt;
&lt;br /&gt;
As krbsnap, run:&lt;br /&gt;
&lt;br /&gt;
  mkdir ~/krb5.git&lt;br /&gt;
  cd ~/krb5.git&lt;br /&gt;
  git init --bare&lt;br /&gt;
&lt;br /&gt;
To populate the git repository, log into drugstore as root, &amp;quot;su -s /bin/bash - yourusername&amp;quot;, and run:&lt;br /&gt;
&lt;br /&gt;
  cd /git/krb5.git&lt;br /&gt;
  GIT_SSH=/git/krb5.git/hooks/ssh-as-krbsnap git push krbsnap&lt;br /&gt;
&lt;br /&gt;
Make sure that /git/krb5.git/config contains a remote named &amp;quot;krbsnap&amp;quot; for krbsnap@krbdev-buildbot.mit.edu, and that the [hooks] section contains an entry &amp;quot;push-to = krbsnap&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
As krbsnap, fetch the git_buildbot.py script ( https://raw.githubusercontent.com/buildbot/buildbot-contrib/master/master/contrib/git_buildbot.py ) into ~/krb5.git/hooks, and modify it to begin with &amp;quot;#!/usr/bin/python3&amp;quot;.  Make sure it is executable.  Run:&lt;br /&gt;
&lt;br /&gt;
  cd ~/krb5.git&lt;br /&gt;
  touch git-daemon-export-ok&lt;br /&gt;
  cd hooks&lt;br /&gt;
  ln -s git_buildbot.py post-receive&lt;br /&gt;
&lt;br /&gt;
As krbsnap, run &amp;quot;crontab -e&amp;quot; and add this entry:&lt;br /&gt;
&lt;br /&gt;
  @reboot git daemon --detach --base-path=$HOME&lt;br /&gt;
&lt;br /&gt;
Run the command by hand to start the daemon initially.&lt;br /&gt;
&lt;br /&gt;
==buildbot worker setup==&lt;br /&gt;
&lt;br /&gt;
For the Solaris buildbot worker, see [[Solaris_Build_Environment]] for platform-specific instructions.&lt;br /&gt;
&lt;br /&gt;
Install the buildbot worker software, using the buildbot-worker package or the platform equivalent.&lt;br /&gt;
&lt;br /&gt;
Install the following Ubuntu packages: autoconf bison build-essential git keyutils ldap-utils libcmocka-dev libkeyutils-dev libldap2-dev liblmdb-dev libresolv-wrapper libsasl2-dev libssl-dev libtool pkg-config python3-kdcproxy python3-pyrad&lt;br /&gt;
&lt;br /&gt;
Install the slapd package.  apt may ask for a master password twice; the value is unimportant and can be left blank.&lt;br /&gt;
&lt;br /&gt;
(TBD: enumerate packages needed for documentation build worker.)&lt;br /&gt;
&lt;br /&gt;
If the platform package does not create a buildbot account, create one with a home directory.  Create an empty .k5login file in the buildbot home directory.  These instructions will assume that the buildbot home directory is /var/lib/buildbot.&lt;br /&gt;
&lt;br /&gt;
As the buildbot account (&amp;quot;su -s /bin/bash - buildbot&amp;quot;), generate a key using:&lt;br /&gt;
&lt;br /&gt;
  ssh-keygen -q -N &amp;quot;&amp;quot; -f .ssh/id_rsa -t rsa&lt;br /&gt;
&lt;br /&gt;
Add the contents of .ssh/id_rsa.pub to ~buildbot/.ssh/authorized_keys on krbdev-buildbot.mit.edu.&lt;br /&gt;
&lt;br /&gt;
Run &amp;quot;ssh -l buildbot krbdev-buildbot.mit.edu&amp;quot; to get the master host key into .ssh/known_hosts.  The correct host key fingerprint of the master can be obtained by running &amp;quot;ssh-keygen -l -E sha256 -f /etc/ssh/ssh_host_ecdsa_key.pub&amp;quot; on krbdev-buildbot.mit.edu (or perhaps ssh_host_rsa_key.pub or ssh_host_dsa_key.pub if the worker has an old ssh client).&lt;br /&gt;
&lt;br /&gt;
Create a &amp;quot;workers&amp;quot; directory in buildbot's home directory and run &amp;quot;buildbot-worker create-worker /var/lib/buildbot/workers/NAME 127.0.0.1:9989 NAME PASSWORD&amp;quot;, using the name and password from the workers.py entry for the worker.&lt;br /&gt;
&lt;br /&gt;
Arrange for the buildbot worker process to be started on boot.  On Ubuntu 18.04, this is accomplished by editing /etc/default/buildbot-worker as root and setting:&lt;br /&gt;
&lt;br /&gt;
  WORKER_ENABLED[1]=1&lt;br /&gt;
  WORKER_NAME[1]=&amp;quot;NAME&amp;quot;&lt;br /&gt;
  WORKER_USER[1]=&amp;quot;buildbot&amp;quot;&lt;br /&gt;
  WORKER_BASEDIR[1]=&amp;quot;/var/lib/buildbot/workers/NAME&amp;quot;&lt;br /&gt;
  WORKER_OPTIONS[1]=&amp;quot;&amp;quot;&lt;br /&gt;
  WORKER_PREFIXCMD[1]=&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Add a cron job for the buildbot account (run &amp;quot;crontab -e&amp;quot; as buildbot) to maintain the ssh tunnel to the master:&lt;br /&gt;
&lt;br /&gt;
  */5 *  *   *   *     exec ssh -oExitOnForwardFailure=yes -l buildbot -N -L9989:127.0.0.1:9989 krbdev-buildbot.mit.edu&lt;br /&gt;
&lt;br /&gt;
Run the command manually (backgrounded, without the &amp;quot;exec&amp;quot;) to start it for the current session.&lt;br /&gt;
&lt;br /&gt;
The worker which runs the documentation build needs the python3-lxml package, and either the python3-cheetah package (requires Ubuntu 18.10 or higher) or the python3-pip package and &amp;quot;pip3 install cheetah3&amp;quot; to be run.&lt;br /&gt;
&lt;br /&gt;
On RHEL workers there are several differences:&lt;br /&gt;
&lt;br /&gt;
* Enable EPEL with the following commands, substituting X with the RHEL version:&lt;br /&gt;
&lt;br /&gt;
  subscription-manager repos --enable codeready-builder-for-rhel-X-$(arch)-rpms&lt;br /&gt;
  dnf -y install https://dl.fedoraproject.org/pub/epel/epel-release-latest-X.noarch.rpm&lt;br /&gt;
&lt;br /&gt;
* Install necessary packages with:&lt;br /&gt;
&lt;br /&gt;
  dnf -y group install &amp;quot;Development Tools&amp;quot;&lt;br /&gt;
  dnf -y install buildbot-worker openldap-devel openldap-clients openldap-servers libcmocka-devel lmdb-devel cyrus-sasl-devel python3-pip&lt;br /&gt;
  pip3 install kdcproxy pyrad&lt;br /&gt;
&lt;br /&gt;
* The user account is named buildbot-worker and its homedir is /var/lib/buildbot/worker, so there is no need to create a &amp;quot;workers&amp;quot; subdirectory.  There appear to be no startup scripts, so add a user cron job &amp;quot;@reboot buildbot-worker start $HOME/NAME&amp;quot; to start the worker process on boot.&lt;br /&gt;
&lt;br /&gt;
==snapshot service==&lt;br /&gt;
&lt;br /&gt;
This service is probably no longer needed, but the setup details are covered here in case it becomes necessary to resurrect it.&lt;br /&gt;
&lt;br /&gt;
In the krbsnap home directory, create a subdirectory &amp;quot;snap&amp;quot; and copy the krbdev/gensnap script from krbdev-services into it.  Also create a keytab for the krbsnap principal in ~/snap/krbsnap.keytab.  Add the cron job to run gensnap from krbdev/krbsnap-crontab to the crontab for the krbsnap account.  (Do not install sync_gitsvn or its cron job; it is defunct.)&lt;br /&gt;
&lt;br /&gt;
The gensnap script updates a working copy for each branch, runs mkrel, and installs the results in krbsnap@aeneas.mit.edu:/var/ftp/pub/kerberos/dist/vaporware-r-us .  These snapshots are used by the old nightly build infrastructure (scripts in /mit/krbdev/testing), which has been supplanted by other CI systems.&lt;/div&gt;</summary>
		<author><name>Ghudson</name></author>	</entry>

	<entry>
		<id>https://k5wiki.kerberos.org/wiki?title=Buildbot_server_configuration&amp;diff=6053</id>
		<title>Buildbot server configuration</title>
		<link rel="alternate" type="text/html" href="https://k5wiki.kerberos.org/wiki?title=Buildbot_server_configuration&amp;diff=6053"/>
				<updated>2025-07-24T18:47:05Z</updated>
		
		<summary type="html">&lt;p&gt;Ghudson: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page contains notes on the setup of the MIT krb5 buildbot master and workers.  The buildbot master is hosted on krbdev-buildbot.mit.edu.  Workers are listed in machines.txt in the krbdev-services repository.&lt;br /&gt;
&lt;br /&gt;
==Operational notes==&lt;br /&gt;
&lt;br /&gt;
To force a new build on all workers, log into krbdev-buildbot.mit.edu, run &amp;quot;su -s /bin/bash - buildbot&amp;quot;, then run &amp;quot;buildbot sendchange -b master -m localhost:9989 -W yourusername@mit.edu&amp;quot; (or similarly for a different branch).&lt;br /&gt;
&lt;br /&gt;
==Packages==&lt;br /&gt;
&lt;br /&gt;
The python3-buildbot package is required for the buildbot master.  The git package is required for the krb5 repository mirror.&lt;br /&gt;
&lt;br /&gt;
Ubuntu 22.04 does not include the buildbot web interface, so it is necessary to install it using pip3:&lt;br /&gt;
&lt;br /&gt;
  apt install python-pip3&lt;br /&gt;
  pip3 install buildbot-www==3.4.0 buildbot-console-view==3.4.0 buildbot-grid-view==3.4.0 buildbot-waterfall-view==3.4.0&lt;br /&gt;
&lt;br /&gt;
The version &amp;quot;3.4.0&amp;quot; should match the system buildbot package version, which can be determined with &amp;quot;dpkg -l buildbot&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
==buildbot master setup==&lt;br /&gt;
&lt;br /&gt;
Run:&lt;br /&gt;
&lt;br /&gt;
  su -s /bin/bash - buildbot&lt;br /&gt;
  touch .k5login&lt;br /&gt;
  rmdir masters workers&lt;br /&gt;
  buildbot create-master -r master&lt;br /&gt;
&lt;br /&gt;
Install buildbot/master.cfg from krbdev-services into /var/lib/buildbot/master.  Copy /var/lib/buildbot/master/workers.py from the old server.  Make sure both files are owned by and readable by buildbot.  If it is necessary to reconstruct workers.py, has the form:&lt;br /&gt;
&lt;br /&gt;
  from buildbot.worker import Worker&lt;br /&gt;
  workers = [&lt;br /&gt;
      Worker('v09', '&amp;lt;password&amp;gt;', properties={'platform': 'amd64-u1204'}),&lt;br /&gt;
      ...&lt;br /&gt;
  ]&lt;br /&gt;
&lt;br /&gt;
The name and password must match the values used on the worker.  The platform is mostly arbitrary and will be used to construct builder entries.  Multiple workers can have the same platform.  The third argument may be omitted for workers that run special tasks (such as the documentation build) and aren't part of the regular platform builds.&lt;br /&gt;
&lt;br /&gt;
Copy over .ssh/authorized_keys from the old server's /var/lib/buildbot.  If it is necessary to reconstruct it, it must contain the ssh key for each worker entry (.ssh/id_rsa.pub from the buildbot account on the worker).&lt;br /&gt;
&lt;br /&gt;
As root, edit /etc/default/buildmaster and change the values so they read:&lt;br /&gt;
&lt;br /&gt;
  MASTER_ENABLED[1]=1&lt;br /&gt;
  MASTER_NAME[1]=&amp;quot;master&amp;quot;&lt;br /&gt;
  MASTER_USER[1]=&amp;quot;buildbot&amp;quot;&lt;br /&gt;
  MASTER_BASEDIR[1]=&amp;quot;/var/lib/buildbot/master&amp;quot;&lt;br /&gt;
  MASTER_OPTIONS[1]=&amp;quot;&amp;quot;&lt;br /&gt;
  MASTER_PREFIXCMD[1]=&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Run &amp;quot;service buildmaster restart&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Install a krbsnap keytab into /var/lib/buildbot, readable only by root.  Install buildbot/doc-update.sh from krbdev-services into /var/lib/buildbot.  Add the following cron job:&lt;br /&gt;
&lt;br /&gt;
  0 4 * * * /var/lib/buildbot/doc-update.sh&lt;br /&gt;
&lt;br /&gt;
==git mirror setup==&lt;br /&gt;
&lt;br /&gt;
The buildbot master host runs a mirror of the drugstore krb5 git repository, for access by workers and to send change notifications to the buildbot master.&lt;br /&gt;
&lt;br /&gt;
Create a krbsnap account using the uid of the Athena krbsnap user:&lt;br /&gt;
&lt;br /&gt;
  useradd -m -u 38160 -s /bin/bash krbsnap&lt;br /&gt;
&lt;br /&gt;
As krbsnap, create ~/.ssh and add the krbsnap key from /git/krb5.git/hooks/krbsnap_rsa_key.pub on drugstore.mit.edu to ~/.ssh/authorized_keys.  (This file may be managed by ops along with the .k5login file, and ops may have created the krbsnap account during provisioning.)&lt;br /&gt;
&lt;br /&gt;
As krbsnap, run:&lt;br /&gt;
&lt;br /&gt;
  mkdir ~/krb5.git&lt;br /&gt;
  cd ~/krb5.git&lt;br /&gt;
  git init --bare&lt;br /&gt;
&lt;br /&gt;
To populate the git repository, log into drugstore as root, &amp;quot;su -s /bin/bash - yourusername&amp;quot;, and run:&lt;br /&gt;
&lt;br /&gt;
  cd /git/krb5.git&lt;br /&gt;
  GIT_SSH=/git/krb5.git/hooks/ssh-as-krbsnap git push krbsnap&lt;br /&gt;
&lt;br /&gt;
Make sure that /git/krb5.git/config contains a remote named &amp;quot;krbsnap&amp;quot; for krbsnap@krbdev-buildbot.mit.edu, and that the [hooks] section contains an entry &amp;quot;push-to = krbsnap&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
As krbsnap, fetch the git_buildbot.py script ( https://raw.githubusercontent.com/buildbot/buildbot-contrib/master/master/contrib/git_buildbot.py ) into ~/krb5.git/hooks, and modify it to begin with &amp;quot;#!/usr/bin/python3&amp;quot;.  Make sure it is executable.  Run:&lt;br /&gt;
&lt;br /&gt;
  cd ~/krb5.git&lt;br /&gt;
  touch git-daemon-export-ok&lt;br /&gt;
  cd hooks&lt;br /&gt;
  ln -s git_buildbot.py post-receive&lt;br /&gt;
&lt;br /&gt;
As krbsnap, run &amp;quot;crontab -e&amp;quot; and add this entry:&lt;br /&gt;
&lt;br /&gt;
  @reboot git daemon --detach --base-path=$HOME&lt;br /&gt;
&lt;br /&gt;
Run the command by hand to start the daemon initially.&lt;br /&gt;
&lt;br /&gt;
==buildbot worker setup==&lt;br /&gt;
&lt;br /&gt;
For the Solaris buildbot worker, see [[Solaris_Build_Environment]] for platform-specific instructions.&lt;br /&gt;
&lt;br /&gt;
Install the buildbot worker software, using the buildbot-worker package or the platform equivalent.&lt;br /&gt;
&lt;br /&gt;
Install the following Ubuntu packages: autoconf bison build-essential git keyutils ldap-utils libcmocka-dev libkeyutils-dev libldap2-dev liblmdb-dev libsasl2-dev libssl-dev libtool pkg-config python3-kdcproxy python3-pip&lt;br /&gt;
&lt;br /&gt;
Install the slapd package.  apt may ask for a master password twice; the value is unimportant and can be left blank.&lt;br /&gt;
&lt;br /&gt;
On Ubuntu 18.04 or later, install libresolv-wrapper.&lt;br /&gt;
&lt;br /&gt;
Run &amp;quot;pip3 install pyrad&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
(TBD: enumerate packages needed for documentation build worker.)&lt;br /&gt;
&lt;br /&gt;
If the platform package does not create a buildbot account, create one with a home directory.  Create an empty .k5login file in the buildbot home directory.  These instructions will assume that the buildbot home directory is /var/lib/buildbot.&lt;br /&gt;
&lt;br /&gt;
As the buildbot account (&amp;quot;su -s /bin/bash - buildbot&amp;quot;), generate a key using:&lt;br /&gt;
&lt;br /&gt;
  ssh-keygen -q -N &amp;quot;&amp;quot; -f .ssh/id_rsa -t rsa&lt;br /&gt;
&lt;br /&gt;
Add the contents of .ssh/id_rsa.pub to ~buildbot/.ssh/authorized_keys on krbdev-buildbot.mit.edu.&lt;br /&gt;
&lt;br /&gt;
Run &amp;quot;ssh -l buildbot krbdev-buildbot.mit.edu&amp;quot; to get the master host key into .ssh/known_hosts.  The correct host key fingerprint of the master can be obtained by running &amp;quot;ssh-keygen -l -E sha256 -f /etc/ssh/ssh_host_ecdsa_key.pub&amp;quot; on krbdev-buildbot.mit.edu (or perhaps ssh_host_rsa_key.pub or ssh_host_dsa_key.pub if the worker has an old ssh client).&lt;br /&gt;
&lt;br /&gt;
Create a &amp;quot;workers&amp;quot; directory in buildbot's home directory and run &amp;quot;buildbot-worker create-worker /var/lib/buildbot/workers/NAME 127.0.0.1:9989 NAME PASSWORD&amp;quot;, using the name and password from the workers.py entry for the worker.&lt;br /&gt;
&lt;br /&gt;
Arrange for the buildbot worker process to be started on boot.  On Ubuntu 18.04, this is accomplished by editing /etc/default/buildbot-worker as root and setting:&lt;br /&gt;
&lt;br /&gt;
  WORKER_ENABLED[1]=1&lt;br /&gt;
  WORKER_NAME[1]=&amp;quot;NAME&amp;quot;&lt;br /&gt;
  WORKER_USER[1]=&amp;quot;buildbot&amp;quot;&lt;br /&gt;
  WORKER_BASEDIR[1]=&amp;quot;/var/lib/buildbot/workers/NAME&amp;quot;&lt;br /&gt;
  WORKER_OPTIONS[1]=&amp;quot;&amp;quot;&lt;br /&gt;
  WORKER_PREFIXCMD[1]=&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Add a cron job for the buildbot account (run &amp;quot;crontab -e&amp;quot; as buildbot) to maintain the ssh tunnel to the master:&lt;br /&gt;
&lt;br /&gt;
  */5 *  *   *   *     exec ssh -oExitOnForwardFailure=yes -l buildbot -N -L9989:127.0.0.1:9989 krbdev-buildbot.mit.edu&lt;br /&gt;
&lt;br /&gt;
Run the command manually (backgrounded, without the &amp;quot;exec&amp;quot;) to start it for the current session.&lt;br /&gt;
&lt;br /&gt;
The worker which runs the documentation build needs the python3-lxml package, and either the python3-cheetah package (requires Ubuntu 18.10 or higher) or the python3-pip package and &amp;quot;pip3 install cheetah3&amp;quot; to be run.&lt;br /&gt;
&lt;br /&gt;
On RHEL workers there are several differences:&lt;br /&gt;
&lt;br /&gt;
* Enable EPEL with the following commands, substituting X with the RHEL version:&lt;br /&gt;
&lt;br /&gt;
  subscription-manager repos --enable codeready-builder-for-rhel-X-$(arch)-rpms&lt;br /&gt;
  dnf -y install https://dl.fedoraproject.org/pub/epel/epel-release-latest-X.noarch.rpm&lt;br /&gt;
&lt;br /&gt;
* Install necessary packages with:&lt;br /&gt;
&lt;br /&gt;
  dnf -y group install &amp;quot;Development Tools&amp;quot;&lt;br /&gt;
  dnf -y install buildbot-worker openldap-devel openldap-clients openldap-servers libcmocka-devel lmdb-devel cyrus-sasl-devel python3-pip&lt;br /&gt;
  pip3 install kdcproxy pyrad&lt;br /&gt;
&lt;br /&gt;
* The user account is named buildbot-worker and its homedir is /var/lib/buildbot/worker, so there is no need to create a &amp;quot;workers&amp;quot; subdirectory.  There appear to be no startup scripts, so add a user cron job &amp;quot;@reboot buildbot-worker start $HOME/NAME&amp;quot; to start the worker process on boot.&lt;br /&gt;
&lt;br /&gt;
==snapshot service==&lt;br /&gt;
&lt;br /&gt;
This service is probably no longer needed, but the setup details are covered here in case it becomes necessary to resurrect it.&lt;br /&gt;
&lt;br /&gt;
In the krbsnap home directory, create a subdirectory &amp;quot;snap&amp;quot; and copy the krbdev/gensnap script from krbdev-services into it.  Also create a keytab for the krbsnap principal in ~/snap/krbsnap.keytab.  Add the cron job to run gensnap from krbdev/krbsnap-crontab to the crontab for the krbsnap account.  (Do not install sync_gitsvn or its cron job; it is defunct.)&lt;br /&gt;
&lt;br /&gt;
The gensnap script updates a working copy for each branch, runs mkrel, and installs the results in krbsnap@aeneas.mit.edu:/var/ftp/pub/kerberos/dist/vaporware-r-us .  These snapshots are used by the old nightly build infrastructure (scripts in /mit/krbdev/testing), which has been supplanted by other CI systems.&lt;/div&gt;</summary>
		<author><name>Ghudson</name></author>	</entry>

	<entry>
		<id>https://k5wiki.kerberos.org/wiki?title=Buildbot_server_configuration&amp;diff=6052</id>
		<title>Buildbot server configuration</title>
		<link rel="alternate" type="text/html" href="https://k5wiki.kerberos.org/wiki?title=Buildbot_server_configuration&amp;diff=6052"/>
				<updated>2025-07-24T16:23:06Z</updated>
		
		<summary type="html">&lt;p&gt;Ghudson: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page contains notes on the setup of the MIT krb5 buildbot master and workers.  The buildbot master is hosted on krbdev-buildbot.mit.edu.  Workers are listed in machines.txt in the krbdev-services repository.&lt;br /&gt;
&lt;br /&gt;
==Operational notes==&lt;br /&gt;
&lt;br /&gt;
To force a new build on all workers, log into krbdev-buildbot.mit.edu, run &amp;quot;su -s /bin/bash - buildbot&amp;quot;, then run &amp;quot;buildbot sendchange -b master -m localhost:9989 -W yourusername@mit.edu&amp;quot; (or similarly for a different branch).&lt;br /&gt;
&lt;br /&gt;
==Packages==&lt;br /&gt;
&lt;br /&gt;
The python3-buildbot package is required for the buildbot master.  The git package is required for the krb5 repository mirror.&lt;br /&gt;
&lt;br /&gt;
Ubuntu 22.04 does not include the buildbot web interface, so it is necessary to install it using pip3:&lt;br /&gt;
&lt;br /&gt;
  apt install python-pip3&lt;br /&gt;
  pip3 install buildbot-www==3.4.0 buildbot-console-view==3.4.0 buildbot-grid-view==3.4.0 buildbot-waterfall-view==3.4.0&lt;br /&gt;
&lt;br /&gt;
The version &amp;quot;3.4.0&amp;quot; should match the system buildbot package version, which can be determined with &amp;quot;dpkg -l buildbot&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
==buildbot master setup==&lt;br /&gt;
&lt;br /&gt;
Run:&lt;br /&gt;
&lt;br /&gt;
  su -s /bin/bash - buildbot&lt;br /&gt;
  touch .k5login&lt;br /&gt;
  rmdir masters workers&lt;br /&gt;
  buildbot create-master -r master&lt;br /&gt;
&lt;br /&gt;
Install buildbot/master.cfg from krbdev-services into /var/lib/buildbot/master.  Copy /var/lib/buildbot/master/workers.py from the old server.  Make sure both files are owned by and readable by buildbot.  If it is necessary to reconstruct workers.py, has the form:&lt;br /&gt;
&lt;br /&gt;
  from buildbot.worker import Worker&lt;br /&gt;
  workers = [&lt;br /&gt;
      Worker('v09', '&amp;lt;password&amp;gt;', properties={'platform': 'amd64-u1204'}),&lt;br /&gt;
      ...&lt;br /&gt;
  ]&lt;br /&gt;
&lt;br /&gt;
The name and password must match the values used on the worker.  The platform is mostly arbitrary and will be used to construct builder entries.  Multiple workers can have the same platform.  The third argument may be omitted for workers that run special tasks (such as the documentation build) and aren't part of the regular platform builds.&lt;br /&gt;
&lt;br /&gt;
Copy over .ssh/authorized_keys from the old server's /var/lib/buildbot.  If it is necessary to reconstruct it, it must contain the ssh key for each worker entry (.ssh/id_rsa.pub from the buildbot account on the worker).&lt;br /&gt;
&lt;br /&gt;
As root, edit /etc/default/buildmaster and change the values so they read:&lt;br /&gt;
&lt;br /&gt;
  MASTER_ENABLED[1]=1&lt;br /&gt;
  MASTER_NAME[1]=&amp;quot;master&amp;quot;&lt;br /&gt;
  MASTER_USER[1]=&amp;quot;buildbot&amp;quot;&lt;br /&gt;
  MASTER_BASEDIR[1]=&amp;quot;/var/lib/buildbot/master&amp;quot;&lt;br /&gt;
  MASTER_OPTIONS[1]=&amp;quot;&amp;quot;&lt;br /&gt;
  MASTER_PREFIXCMD[1]=&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Run &amp;quot;service buildmaster restart&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Install a krbsnap keytab into /var/lib/buildbot, readable only by root.  Install buildbot/doc-update.sh from krbdev-services into /var/lib/buildbot.  Add the following cron job:&lt;br /&gt;
&lt;br /&gt;
  0 4 * * * /var/lib/buildbot/doc-update.sh&lt;br /&gt;
&lt;br /&gt;
==git mirror setup==&lt;br /&gt;
&lt;br /&gt;
The buildbot master host runs a mirror of the drugstore krb5 git repository, for access by workers and to send change notifications to the buildbot master.&lt;br /&gt;
&lt;br /&gt;
Create a krbsnap account using the uid of the Athena krbsnap user:&lt;br /&gt;
&lt;br /&gt;
  useradd -m -u 38160 -s /bin/bash krbsnap&lt;br /&gt;
&lt;br /&gt;
As krbsnap, create ~/.ssh and add the krbsnap key from /git/krb5.git/hooks/krbsnap_rsa_key.pub on drugstore.mit.edu to ~/.ssh/authorized_keys.  (This file may be managed by ops along with the .k5login file, and ops may have created the krbsnap account during provisioning.)&lt;br /&gt;
&lt;br /&gt;
As krbsnap, run:&lt;br /&gt;
&lt;br /&gt;
  mkdir ~/krb5.git&lt;br /&gt;
  cd ~/krb5.git&lt;br /&gt;
  git init --bare&lt;br /&gt;
&lt;br /&gt;
To populate the git repository, log into drugstore as root, &amp;quot;su -s /bin/bash - yourusername&amp;quot;, and run:&lt;br /&gt;
&lt;br /&gt;
  cd /git/krb5.git&lt;br /&gt;
  GIT_SSH=/git/krb5.git/hooks/ssh-as-krbsnap git push krbsnap&lt;br /&gt;
&lt;br /&gt;
Make sure that /git/krb5.git/config contains a remote named &amp;quot;krbsnap&amp;quot; for krbsnap@krbdev-buildbot.mit.edu, and that the [hooks] section contains an entry &amp;quot;push-to = krbsnap&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
As krbsnap, fetch the git_buildbot.py script ( https://raw.githubusercontent.com/buildbot/buildbot-contrib/master/master/contrib/git_buildbot.py ) into ~/krb5.git/hooks, and modify it to begin with &amp;quot;#!/usr/bin/python3&amp;quot;.  Make sure it is executable.  Run:&lt;br /&gt;
&lt;br /&gt;
  cd ~/krb5.git&lt;br /&gt;
  touch git-daemon-export-ok&lt;br /&gt;
  cd hooks&lt;br /&gt;
  ln -s git_buildbot.py post-receive&lt;br /&gt;
&lt;br /&gt;
As krbsnap, run &amp;quot;crontab -e&amp;quot; and add this entry:&lt;br /&gt;
&lt;br /&gt;
  @reboot git daemon --detach --base-path=$HOME&lt;br /&gt;
&lt;br /&gt;
Run the command by hand to start the daemon initially.&lt;br /&gt;
&lt;br /&gt;
==buildbot worker setup==&lt;br /&gt;
&lt;br /&gt;
For the Solaris buildbot worker, see [[Solaris_Build_Environment]] for platform-specific instructions.&lt;br /&gt;
&lt;br /&gt;
Install the buildbot worker software, using the python3-buildbot-worker package or the platform equivalent.&lt;br /&gt;
&lt;br /&gt;
Install the following Ubuntu packages: autoconf bison build-essential git keyutils ldap-utils libcmocka-dev libkeyutils-dev libldap2-dev liblmdb-dev libsasl2-dev libssl-dev libtool pkg-config python3-kdcproxy python3-pip&lt;br /&gt;
&lt;br /&gt;
Install the slapd package.  apt may ask for a master password twice; the value is unimportant and can be left blank.&lt;br /&gt;
&lt;br /&gt;
On Ubuntu 18.04 or later, install libresolv-wrapper.&lt;br /&gt;
&lt;br /&gt;
Run &amp;quot;pip3 install pyrad&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
(TBD: enumerate packages needed for documentation build worker.)&lt;br /&gt;
&lt;br /&gt;
If the platform package does not create a buildbot account, create one with a home directory.  Create an empty .k5login file in the buildbot home directory.  These instructions will assume that the buildbot home directory is /var/lib/buildbot.&lt;br /&gt;
&lt;br /&gt;
As the buildbot account (&amp;quot;su -s /bin/bash - buildbot&amp;quot;), generate a key using:&lt;br /&gt;
&lt;br /&gt;
  ssh-keygen -q -N &amp;quot;&amp;quot; -f .ssh/id_rsa -t rsa&lt;br /&gt;
&lt;br /&gt;
Add the contents of .ssh/id_rsa.pub to ~buildbot/.ssh/authorized_keys on krbdev-buildbot.mit.edu.&lt;br /&gt;
&lt;br /&gt;
Run &amp;quot;ssh -l buildbot krbdev-buildbot.mit.edu&amp;quot; to get the master host key into .ssh/known_hosts.  The correct host key fingerprint of the master can be obtained by running &amp;quot;ssh-keygen -l -E sha256 -f /etc/ssh/ssh_host_ecdsa_key.pub&amp;quot; on krbdev-buildbot.mit.edu (or perhaps ssh_host_rsa_key.pub or ssh_host_dsa_key.pub if the worker has an old ssh client).&lt;br /&gt;
&lt;br /&gt;
Create a &amp;quot;workers&amp;quot; directory in buildbot's home directory and run &amp;quot;buildbot-worker create-worker /var/lib/buildbot/workers/NAME 127.0.0.1:9989 NAME PASSWORD&amp;quot;, using the name and password from the workers.py entry for the worker.&lt;br /&gt;
&lt;br /&gt;
Arrange for the buildbot worker process to be started on boot.  On Ubuntu 18.04, this is accomplished by editing /etc/default/buildbot-worker as root and setting:&lt;br /&gt;
&lt;br /&gt;
  WORKER_ENABLED[1]=1&lt;br /&gt;
  WORKER_NAME[1]=&amp;quot;NAME&amp;quot;&lt;br /&gt;
  WORKER_USER[1]=&amp;quot;buildbot&amp;quot;&lt;br /&gt;
  WORKER_BASEDIR[1]=&amp;quot;/var/lib/buildbot/workers/NAME&amp;quot;&lt;br /&gt;
  WORKER_OPTIONS[1]=&amp;quot;&amp;quot;&lt;br /&gt;
  WORKER_PREFIXCMD[1]=&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Add a cron job for the buildbot account (run &amp;quot;crontab -e&amp;quot; as buildbot) to maintain the ssh tunnel to the master:&lt;br /&gt;
&lt;br /&gt;
  */5 *  *   *   *     exec ssh -oExitOnForwardFailure=yes -l buildbot -N -L9989:127.0.0.1:9989 krbdev-buildbot.mit.edu&lt;br /&gt;
&lt;br /&gt;
Run the command manually (backgrounded, without the &amp;quot;exec&amp;quot;) to start it for the current session.&lt;br /&gt;
&lt;br /&gt;
The worker which runs the documentation build needs the python3-lxml package, and either the python3-cheetah package (requires Ubuntu 18.10 or higher) or the python3-pip package and &amp;quot;pip3 install cheetah3&amp;quot; to be run.&lt;br /&gt;
&lt;br /&gt;
On RHEL workers there are several differences:&lt;br /&gt;
&lt;br /&gt;
* Enable EPEL with the following commands, substituting X with the RHEL version:&lt;br /&gt;
&lt;br /&gt;
  subscription-manager repos --enable codeready-builder-for-rhel-X-$(arch)-rpms&lt;br /&gt;
  dnf -y install https://dl.fedoraproject.org/pub/epel/epel-release-latest-X.noarch.rpm&lt;br /&gt;
&lt;br /&gt;
* Install necessary packages with:&lt;br /&gt;
&lt;br /&gt;
  dnf -y group install &amp;quot;Development Tools&amp;quot;&lt;br /&gt;
  dnf -y install buildbot-worker openldap-devel openldap-clients openldap-servers libcmocka-devel lmdb-devel cyrus-sasl-devel python3-pip&lt;br /&gt;
  pip3 install kdcproxy pyrad&lt;br /&gt;
&lt;br /&gt;
* The user account is named buildbot-worker and its homedir is /var/lib/buildbot/worker, so there is no need to create a &amp;quot;workers&amp;quot; subdirectory.  There appear to be no startup scripts, so add a user cron job &amp;quot;@reboot buildbot-worker start $HOME/NAME&amp;quot; to start the worker process on boot.&lt;br /&gt;
&lt;br /&gt;
==snapshot service==&lt;br /&gt;
&lt;br /&gt;
This service is probably no longer needed, but the setup details are covered here in case it becomes necessary to resurrect it.&lt;br /&gt;
&lt;br /&gt;
In the krbsnap home directory, create a subdirectory &amp;quot;snap&amp;quot; and copy the krbdev/gensnap script from krbdev-services into it.  Also create a keytab for the krbsnap principal in ~/snap/krbsnap.keytab.  Add the cron job to run gensnap from krbdev/krbsnap-crontab to the crontab for the krbsnap account.  (Do not install sync_gitsvn or its cron job; it is defunct.)&lt;br /&gt;
&lt;br /&gt;
The gensnap script updates a working copy for each branch, runs mkrel, and installs the results in krbsnap@aeneas.mit.edu:/var/ftp/pub/kerberos/dist/vaporware-r-us .  These snapshots are used by the old nightly build infrastructure (scripts in /mit/krbdev/testing), which has been supplanted by other CI systems.&lt;/div&gt;</summary>
		<author><name>Ghudson</name></author>	</entry>

	<entry>
		<id>https://k5wiki.kerberos.org/wiki?title=Buildbot_server_configuration&amp;diff=6051</id>
		<title>Buildbot server configuration</title>
		<link rel="alternate" type="text/html" href="https://k5wiki.kerberos.org/wiki?title=Buildbot_server_configuration&amp;diff=6051"/>
				<updated>2025-07-24T16:05:53Z</updated>
		
		<summary type="html">&lt;p&gt;Ghudson: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page contains notes on the setup of the MIT krb5 buildbot master and workers.  The buildbot master is hosted on krbdev-buildbot.mit.edu.  Workers are listed in machines.txt in the krbdev-services repository.&lt;br /&gt;
&lt;br /&gt;
==Operational notes==&lt;br /&gt;
&lt;br /&gt;
To force a new build on all workers, log into krbdev-buildbot.mit.edu, run &amp;quot;su -s /bin/bash - buildbot&amp;quot;, then run &amp;quot;buildbot sendchange -b master -m localhost:9989 -W yourusername@mit.edu&amp;quot; (or similarly for a different branch).&lt;br /&gt;
&lt;br /&gt;
==Packages==&lt;br /&gt;
&lt;br /&gt;
The python3-buildbot package is required for the buildbot master.  The git package is required for the krb5 repository mirror.&lt;br /&gt;
&lt;br /&gt;
Ubuntu 22.04 does not include the buildbot web interface, so it is necessary to install it using pip3:&lt;br /&gt;
&lt;br /&gt;
  apt install python-pip3&lt;br /&gt;
  pip3 install buildbot-www==3.4.0 buildbot-console-view==3.4.0 buildbot-grid-view==3.4.0 buildbot-waterfall-view==3.4.0&lt;br /&gt;
&lt;br /&gt;
The version &amp;quot;3.4.0&amp;quot; should match the system buildbot package version, which can be determined with &amp;quot;dpkg -l buildbot&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
==buildbot master setup==&lt;br /&gt;
&lt;br /&gt;
Run:&lt;br /&gt;
&lt;br /&gt;
  su -s /bin/bash - buildbot&lt;br /&gt;
  touch .k5login&lt;br /&gt;
  rmdir masters workers&lt;br /&gt;
  buildbot create-master -r master&lt;br /&gt;
&lt;br /&gt;
Install buildbot/master.cfg from krbdev-services into /var/lib/buildbot/master.  Copy /var/lib/buildbot/master/workers.py from the old server.  Make sure both files are owned by and readable by buildbot.  If it is necessary to reconstruct workers.py, has the form:&lt;br /&gt;
&lt;br /&gt;
  from buildbot.worker import Worker&lt;br /&gt;
  workers = [&lt;br /&gt;
      Worker('v09', '&amp;lt;password&amp;gt;', properties={'platform': 'amd64-u1204'}),&lt;br /&gt;
      ...&lt;br /&gt;
  ]&lt;br /&gt;
&lt;br /&gt;
The name and password must match the values used on the worker.  The platform is mostly arbitrary and will be used to construct builder entries.  Multiple workers can have the same platform.  The third argument may be omitted for workers that run special tasks (such as the documentation build) and aren't part of the regular platform builds.&lt;br /&gt;
&lt;br /&gt;
Copy over .ssh/authorized_keys from the old server's /var/lib/buildbot.  If it is necessary to reconstruct it, it must contain the ssh key for each worker entry (.ssh/id_rsa.pub from the buildbot account on the worker).&lt;br /&gt;
&lt;br /&gt;
As root, edit /etc/default/buildmaster and change the values so they read:&lt;br /&gt;
&lt;br /&gt;
  MASTER_ENABLED[1]=1&lt;br /&gt;
  MASTER_NAME[1]=&amp;quot;master&amp;quot;&lt;br /&gt;
  MASTER_USER[1]=&amp;quot;buildbot&amp;quot;&lt;br /&gt;
  MASTER_BASEDIR[1]=&amp;quot;/var/lib/buildbot/master&amp;quot;&lt;br /&gt;
  MASTER_OPTIONS[1]=&amp;quot;&amp;quot;&lt;br /&gt;
  MASTER_PREFIXCMD[1]=&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Run &amp;quot;service buildmaster restart&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Install a krbsnap keytab into /var/lib/buildbot, readable only by root.  Install buildbot/doc-update.sh from krbdev-services into /var/lib/buildbot.  Add the following cron job:&lt;br /&gt;
&lt;br /&gt;
  0 4 * * * /var/lib/buildbot/doc-update.sh&lt;br /&gt;
&lt;br /&gt;
==git mirror setup==&lt;br /&gt;
&lt;br /&gt;
The buildbot master host runs a mirror of the drugstore krb5 git repository, for access by workers and to send change notifications to the buildbot master.&lt;br /&gt;
&lt;br /&gt;
Create a krbsnap account using the uid of the Athena krbsnap user:&lt;br /&gt;
&lt;br /&gt;
  useradd -m -u 38160 -s /bin/bash krbsnap&lt;br /&gt;
&lt;br /&gt;
As krbsnap, create ~/.ssh and add the krbsnap key from /git/krb5.git/hooks/krbsnap_rsa_key.pub on drugstore.mit.edu to ~/.ssh/authorized_keys.  (This file may be managed by ops along with the .k5login file, and ops may have created the krbsnap account during provisioning.)&lt;br /&gt;
&lt;br /&gt;
As krbsnap, run:&lt;br /&gt;
&lt;br /&gt;
  mkdir ~/krb5.git&lt;br /&gt;
  cd ~/krb5.git&lt;br /&gt;
  git init --bare&lt;br /&gt;
&lt;br /&gt;
To populate the git repository, log into drugstore as root, &amp;quot;su -s /bin/bash - yourusername&amp;quot;, and run:&lt;br /&gt;
&lt;br /&gt;
  cd /git/krb5.git&lt;br /&gt;
  GIT_SSH=/git/krb5.git/hooks/ssh-as-krbsnap git push krbsnap&lt;br /&gt;
&lt;br /&gt;
Make sure that /git/krb5.git/config contains a remote named &amp;quot;krbsnap&amp;quot; for krbsnap@krbdev-buildbot.mit.edu, and that the [hooks] section contains an entry &amp;quot;push-to = krbsnap&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
As krbsnap, fetch the git_buildbot.py script ( https://raw.githubusercontent.com/buildbot/buildbot-contrib/master/master/contrib/git_buildbot.py ) into ~/krb5.git/hooks, and modify it to begin with &amp;quot;#!/usr/bin/python3&amp;quot;.  Make sure it is executable.  Run:&lt;br /&gt;
&lt;br /&gt;
  cd ~/krb5.git&lt;br /&gt;
  touch git-daemon-export-ok&lt;br /&gt;
  cd hooks&lt;br /&gt;
  ln -s git_buildbot.py post-receive&lt;br /&gt;
&lt;br /&gt;
As krbsnap, run &amp;quot;crontab -e&amp;quot; and add this entry:&lt;br /&gt;
&lt;br /&gt;
  @reboot git daemon --detach --base-path=$HOME&lt;br /&gt;
&lt;br /&gt;
Run the command by hand to start the daemon initially.&lt;br /&gt;
&lt;br /&gt;
==buildbot worker setup==&lt;br /&gt;
&lt;br /&gt;
For the Solaris buildbot worker, see [[Solaris_Build_Environment]] for platform-specific instructions.&lt;br /&gt;
&lt;br /&gt;
Install the buildbot worker software, using the python3-buildbot-worker package or the platform equivalent.&lt;br /&gt;
&lt;br /&gt;
Install the following Ubuntu packages: autoconf bison build-essential git keyutils ldap-utils libcmocka-dev libkeyutils-dev libldap2-dev liblmdb-dev libsasl2-dev libssl-dev libtool pkg-config python3-kdcproxy python3-pip&lt;br /&gt;
&lt;br /&gt;
Install the slapd package.  apt may ask for a master password twice; the value is unimportant and can be left blank.&lt;br /&gt;
&lt;br /&gt;
On Ubuntu 18.04 or later, install libresolv-wrapper.&lt;br /&gt;
&lt;br /&gt;
Run &amp;quot;pip3 install pyrad&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
(TBD: enumerate packages needed for documentation build worker.)&lt;br /&gt;
&lt;br /&gt;
If the platform package does not create a buildbot account, create one with a home directory.  Create an empty .k5login file in the buildbot home directory.  These instructions will assume that the buildbot home directory is /var/lib/buildbot.&lt;br /&gt;
&lt;br /&gt;
As the buildbot account (&amp;quot;su -s /bin/bash - buildbot&amp;quot;), generate a key using:&lt;br /&gt;
&lt;br /&gt;
  ssh-keygen -q -N &amp;quot;&amp;quot; -f .ssh/id_rsa -t rsa&lt;br /&gt;
&lt;br /&gt;
Add the contents of .ssh/id_rsa.pub to ~buildbot/.ssh/authorized_keys on krbdev-buildbot.mit.edu.&lt;br /&gt;
&lt;br /&gt;
Run &amp;quot;ssh -l buildbot krbdev-buildbot.mit.edu&amp;quot; to get the master host key into .ssh/known_hosts.  The correct host key fingerprint of the master can be obtained by running &amp;quot;ssh-keygen -l -E sha256 -f /etc/ssh/ssh_host_ecdsa_key.pub&amp;quot; on krbdev-buildbot.mit.edu (or perhaps ssh_host_rsa_key.pub or ssh_host_dsa_key.pub if the worker has an old ssh client).&lt;br /&gt;
&lt;br /&gt;
Create a &amp;quot;workers&amp;quot; directory in buildbot's home directory and run &amp;quot;buildbot-worker create-worker /var/lib/buildbot/workers/NAME 127.0.0.1:9989 NAME PASSWORD&amp;quot;, using the name and password from the workers.py entry for the worker.&lt;br /&gt;
&lt;br /&gt;
Arrange for the buildbot worker process to be started on boot.  On Ubuntu 18.04, this is accomplished by editing /etc/default/buildbot-worker as root and setting:&lt;br /&gt;
&lt;br /&gt;
  WORKER_ENABLED[1]=1&lt;br /&gt;
  WORKER_NAME[1]=&amp;quot;NAME&amp;quot;&lt;br /&gt;
  WORKER_USER[1]=&amp;quot;buildbot&amp;quot;&lt;br /&gt;
  WORKER_BASEDIR[1]=&amp;quot;/var/lib/buildbot/workers/NAME&amp;quot;&lt;br /&gt;
  WORKER_OPTIONS[1]=&amp;quot;&amp;quot;&lt;br /&gt;
  WORKER_PREFIXCMD[1]=&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Add a cron job for the buildbot account (run &amp;quot;crontab -e&amp;quot; as buildbot) to maintain the ssh tunnel to the master:&lt;br /&gt;
&lt;br /&gt;
  */5 *  *   *   *     exec ssh -oExitOnForwardFailure=yes -l buildbot -N -L9989:127.0.0.1:9989 krbdev-buildbot.mit.edu&lt;br /&gt;
&lt;br /&gt;
Run the command manually (backgrounded, without the &amp;quot;exec&amp;quot;) to start it for the current session.&lt;br /&gt;
&lt;br /&gt;
The worker which runs the documentation build needs the python3-lxml package, and either the python3-cheetah package (requires Ubuntu 18.10 or higher) or the python3-pip package and &amp;quot;pip3 install cheetah3&amp;quot; to be run.&lt;br /&gt;
&lt;br /&gt;
On RHEL workers there are several differences:&lt;br /&gt;
&lt;br /&gt;
* Enable EPEL with the following commands, substituting X with the RHEL version:&lt;br /&gt;
&lt;br /&gt;
  subscription-manager repos --enable codeready-builder-for-rhel-X-$(arch)-rpms&lt;br /&gt;
  dnf -y install https://dl.fedoraproject.org/pub/epel/epel-release-latest-X.noarch.rpm&lt;br /&gt;
&lt;br /&gt;
* Install necessary packages with:&lt;br /&gt;
&lt;br /&gt;
  dnf -y group install &amp;quot;Development Tools&amp;quot;&lt;br /&gt;
  dnf -y install buildbot-worker openldap-devel openldap-clients openldap-servers libcmocka-devel lmdb-devel cyrus-sasl-devel&lt;br /&gt;
  pip3 install kdcproxy pyrad&lt;br /&gt;
&lt;br /&gt;
* The user account is named buildbot-worker and its homedir is /var/lib/buildbot/worker, so there is no need to create a &amp;quot;workers&amp;quot; subdirectory.  There appear to be no startup scripts, so add a user cron job &amp;quot;@reboot buildbot-worker start $HOME/NAME&amp;quot; to start the worker process on boot.&lt;br /&gt;
&lt;br /&gt;
==snapshot service==&lt;br /&gt;
&lt;br /&gt;
This service is probably no longer needed, but the setup details are covered here in case it becomes necessary to resurrect it.&lt;br /&gt;
&lt;br /&gt;
In the krbsnap home directory, create a subdirectory &amp;quot;snap&amp;quot; and copy the krbdev/gensnap script from krbdev-services into it.  Also create a keytab for the krbsnap principal in ~/snap/krbsnap.keytab.  Add the cron job to run gensnap from krbdev/krbsnap-crontab to the crontab for the krbsnap account.  (Do not install sync_gitsvn or its cron job; it is defunct.)&lt;br /&gt;
&lt;br /&gt;
The gensnap script updates a working copy for each branch, runs mkrel, and installs the results in krbsnap@aeneas.mit.edu:/var/ftp/pub/kerberos/dist/vaporware-r-us .  These snapshots are used by the old nightly build infrastructure (scripts in /mit/krbdev/testing), which has been supplanted by other CI systems.&lt;/div&gt;</summary>
		<author><name>Ghudson</name></author>	</entry>

	<entry>
		<id>https://k5wiki.kerberos.org/wiki?title=Buildbot_server_configuration&amp;diff=6050</id>
		<title>Buildbot server configuration</title>
		<link rel="alternate" type="text/html" href="https://k5wiki.kerberos.org/wiki?title=Buildbot_server_configuration&amp;diff=6050"/>
				<updated>2025-07-24T16:04:57Z</updated>
		
		<summary type="html">&lt;p&gt;Ghudson: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page contains notes on the setup of the MIT krb5 buildbot master and workers.  The buildbot master is hosted on krbdev-buildbot.mit.edu.  Workers are listed in machines.txt in the krbdev-services repository.&lt;br /&gt;
&lt;br /&gt;
==Operational notes==&lt;br /&gt;
&lt;br /&gt;
To force a new build on all workers, log into krbdev-buildbot.mit.edu, run &amp;quot;su -s /bin/bash - buildbot&amp;quot;, then run &amp;quot;buildbot sendchange -b master -m localhost:9989 -W yourusername@mit.edu&amp;quot; (or similarly for a different branch).&lt;br /&gt;
&lt;br /&gt;
==Packages==&lt;br /&gt;
&lt;br /&gt;
The python3-buildbot package is required for the buildbot master.  The git package is required for the krb5 repository mirror.&lt;br /&gt;
&lt;br /&gt;
Ubuntu 22.04 does not include the buildbot web interface, so it is necessary to install it using pip3:&lt;br /&gt;
&lt;br /&gt;
  apt install python-pip3&lt;br /&gt;
  pip3 install buildbot-www==3.4.0 buildbot-console-view==3.4.0 buildbot-grid-view==3.4.0 buildbot-waterfall-view==3.4.0&lt;br /&gt;
&lt;br /&gt;
The version &amp;quot;3.4.0&amp;quot; should match the system buildbot package version, which can be determined with &amp;quot;dpkg -l buildbot&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
==buildbot master setup==&lt;br /&gt;
&lt;br /&gt;
Run:&lt;br /&gt;
&lt;br /&gt;
  su -s /bin/bash - buildbot&lt;br /&gt;
  touch .k5login&lt;br /&gt;
  rmdir masters workers&lt;br /&gt;
  buildbot create-master -r master&lt;br /&gt;
&lt;br /&gt;
Install buildbot/master.cfg from krbdev-services into /var/lib/buildbot/master.  Copy /var/lib/buildbot/master/workers.py from the old server.  Make sure both files are owned by and readable by buildbot.  If it is necessary to reconstruct workers.py, has the form:&lt;br /&gt;
&lt;br /&gt;
  from buildbot.worker import Worker&lt;br /&gt;
  workers = [&lt;br /&gt;
      Worker('v09', '&amp;lt;password&amp;gt;', properties={'platform': 'amd64-u1204'}),&lt;br /&gt;
      ...&lt;br /&gt;
  ]&lt;br /&gt;
&lt;br /&gt;
The name and password must match the values used on the worker.  The platform is mostly arbitrary and will be used to construct builder entries.  Multiple workers can have the same platform.  The third argument may be omitted for workers that run special tasks (such as the documentation build) and aren't part of the regular platform builds.&lt;br /&gt;
&lt;br /&gt;
Copy over .ssh/authorized_keys from the old server's /var/lib/buildbot.  If it is necessary to reconstruct it, it must contain the ssh key for each worker entry (.ssh/id_rsa.pub from the buildbot account on the worker).&lt;br /&gt;
&lt;br /&gt;
As root, edit /etc/default/buildmaster and change the values so they read:&lt;br /&gt;
&lt;br /&gt;
  MASTER_ENABLED[1]=1&lt;br /&gt;
  MASTER_NAME[1]=&amp;quot;master&amp;quot;&lt;br /&gt;
  MASTER_USER[1]=&amp;quot;buildbot&amp;quot;&lt;br /&gt;
  MASTER_BASEDIR[1]=&amp;quot;/var/lib/buildbot/master&amp;quot;&lt;br /&gt;
  MASTER_OPTIONS[1]=&amp;quot;&amp;quot;&lt;br /&gt;
  MASTER_PREFIXCMD[1]=&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Run &amp;quot;service buildmaster restart&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Install a krbsnap keytab into /var/lib/buildbot, readable only by root.  Install buildbot/doc-update.sh from krbdev-services into /var/lib/buildbot.  Add the following cron job:&lt;br /&gt;
&lt;br /&gt;
  0 4 * * * /var/lib/buildbot/doc-update.sh&lt;br /&gt;
&lt;br /&gt;
==git mirror setup==&lt;br /&gt;
&lt;br /&gt;
The buildbot master host runs a mirror of the drugstore krb5 git repository, for access by workers and to send change notifications to the buildbot master.&lt;br /&gt;
&lt;br /&gt;
Create a krbsnap account using the uid of the Athena krbsnap user:&lt;br /&gt;
&lt;br /&gt;
  useradd -m -u 38160 -s /bin/bash krbsnap&lt;br /&gt;
&lt;br /&gt;
As krbsnap, create ~/.ssh and add the krbsnap key from /git/krb5.git/hooks/krbsnap_rsa_key.pub on drugstore.mit.edu to ~/.ssh/authorized_keys.  (This file may be managed by ops along with the .k5login file, and ops may have created the krbsnap account during provisioning.)&lt;br /&gt;
&lt;br /&gt;
As krbsnap, run:&lt;br /&gt;
&lt;br /&gt;
  mkdir ~/krb5.git&lt;br /&gt;
  cd ~/krb5.git&lt;br /&gt;
  git init --bare&lt;br /&gt;
&lt;br /&gt;
To populate the git repository, log into drugstore as root, &amp;quot;su -s /bin/bash - yourusername&amp;quot;, and run:&lt;br /&gt;
&lt;br /&gt;
  cd /git/krb5.git&lt;br /&gt;
  GIT_SSH=/git/krb5.git/hooks/ssh-as-krbsnap git push krbsnap&lt;br /&gt;
&lt;br /&gt;
Make sure that /git/krb5.git/config contains a remote named &amp;quot;krbsnap&amp;quot; for krbsnap@krbdev-buildbot.mit.edu, and that the [hooks] section contains an entry &amp;quot;push-to = krbsnap&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
As krbsnap, fetch the git_buildbot.py script ( https://raw.githubusercontent.com/buildbot/buildbot-contrib/master/master/contrib/git_buildbot.py ) into ~/krb5.git/hooks, and modify it to begin with &amp;quot;#!/usr/bin/python3&amp;quot;.  Make sure it is executable.  Run:&lt;br /&gt;
&lt;br /&gt;
  cd ~/krb5.git&lt;br /&gt;
  touch git-daemon-export-ok&lt;br /&gt;
  cd hooks&lt;br /&gt;
  ln -s git_buildbot.py post-receive&lt;br /&gt;
&lt;br /&gt;
As krbsnap, run &amp;quot;crontab -e&amp;quot; and add this entry:&lt;br /&gt;
&lt;br /&gt;
  @reboot git daemon --detach --base-path=$HOME&lt;br /&gt;
&lt;br /&gt;
Run the command by hand to start the daemon initially.&lt;br /&gt;
&lt;br /&gt;
==buildbot worker setup==&lt;br /&gt;
&lt;br /&gt;
For the Solaris buildbot worker, see [[Solaris_Build_Environment]] for platform-specific instructions.&lt;br /&gt;
&lt;br /&gt;
Install the buildbot worker software, using the python3-buildbot-worker package (buildbot-slave prior to Ubuntu 18.04) or the platform equivalent.&lt;br /&gt;
&lt;br /&gt;
Install the following Ubuntu packages: autoconf bison build-essential git keyutils ldap-utils libcmocka-dev libkeyutils-dev libldap2-dev liblmdb-dev libsasl2-dev libssl-dev libtool pkg-config python3-kdcproxy python3-pip&lt;br /&gt;
&lt;br /&gt;
Install the slapd package.  apt may ask for a master password twice; the value is unimportant and can be left blank.&lt;br /&gt;
&lt;br /&gt;
On Ubuntu 18.04 or later, install libresolv-wrapper.&lt;br /&gt;
&lt;br /&gt;
Run &amp;quot;pip3 install pyrad&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
(TBD: enumerate packages needed for documentation build worker.)&lt;br /&gt;
&lt;br /&gt;
If the platform package does not create a buildbot account, create one with a home directory.  Create an empty .k5login file in the buildbot home directory.  These instructions will assume that the buildbot home directory is /var/lib/buildbot.&lt;br /&gt;
&lt;br /&gt;
As the buildbot account (&amp;quot;su -s /bin/bash - buildbot&amp;quot;), generate a key using:&lt;br /&gt;
&lt;br /&gt;
  ssh-keygen -q -N &amp;quot;&amp;quot; -f .ssh/id_rsa -t rsa&lt;br /&gt;
&lt;br /&gt;
Add the contents of .ssh/id_rsa.pub to ~buildbot/.ssh/authorized_keys on krbdev-buildbot.mit.edu.&lt;br /&gt;
&lt;br /&gt;
Run &amp;quot;ssh -l buildbot krbdev-buildbot.mit.edu&amp;quot; to get the master host key into .ssh/known_hosts.  The correct host key fingerprint of the master can be obtained by running &amp;quot;ssh-keygen -l -E sha256 -f /etc/ssh/ssh_host_ecdsa_key.pub&amp;quot; on krbdev-buildbot.mit.edu (or perhaps ssh_host_rsa_key.pub or ssh_host_dsa_key.pub if the worker has an old ssh client).&lt;br /&gt;
&lt;br /&gt;
Create a &amp;quot;workers&amp;quot; directory in buildbot's home directory and run &amp;quot;buildbot-worker create-worker /var/lib/buildbot/workers/NAME 127.0.0.1:9989 NAME PASSWORD&amp;quot;, using the name and password from the workers.py entry for the worker.&lt;br /&gt;
&lt;br /&gt;
Arrange for the buildbot worker process to be started on boot.  On Ubuntu 18.04, this is accomplished by editing /etc/default/buildbot-worker as root and setting:&lt;br /&gt;
&lt;br /&gt;
  WORKER_ENABLED[1]=1&lt;br /&gt;
  WORKER_NAME[1]=&amp;quot;NAME&amp;quot;&lt;br /&gt;
  WORKER_USER[1]=&amp;quot;buildbot&amp;quot;&lt;br /&gt;
  WORKER_BASEDIR[1]=&amp;quot;/var/lib/buildbot/workers/NAME&amp;quot;&lt;br /&gt;
  WORKER_OPTIONS[1]=&amp;quot;&amp;quot;&lt;br /&gt;
  WORKER_PREFIXCMD[1]=&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Add a cron job for the buildbot account (run &amp;quot;crontab -e&amp;quot; as buildbot) to maintain the ssh tunnel to the master:&lt;br /&gt;
&lt;br /&gt;
  */5 *  *   *   *     exec ssh -oExitOnForwardFailure=yes -l buildbot -N -L9989:127.0.0.1:9989 krbdev-buildbot.mit.edu&lt;br /&gt;
&lt;br /&gt;
Run the command manually (backgrounded, without the &amp;quot;exec&amp;quot;) to start it for the current session.&lt;br /&gt;
&lt;br /&gt;
The worker which runs the documentation build needs the python3-lxml package, and either the python3-cheetah package (requires Ubuntu 18.10 or higher) or the python3-pip package and &amp;quot;pip3 install cheetah3&amp;quot; to be run.&lt;br /&gt;
&lt;br /&gt;
On RHEL workers there are several differences:&lt;br /&gt;
&lt;br /&gt;
* Enable EPEL with the following commands, substituting X with the RHEL version:&lt;br /&gt;
&lt;br /&gt;
  subscription-manager repos --enable codeready-builder-for-rhel-X-$(arch)-rpms&lt;br /&gt;
  dnf -y install https://dl.fedoraproject.org/pub/epel/epel-release-latest-X.noarch.rpm&lt;br /&gt;
&lt;br /&gt;
* Install necessary packages with:&lt;br /&gt;
&lt;br /&gt;
  dnf -y group install &amp;quot;Development Tools&amp;quot;&lt;br /&gt;
  dnf -y install buildbot-worker openldap-devel openldap-clients openldap-servers libcmocka-devel lmdb-devel cyrus-sasl-devel&lt;br /&gt;
  pip3 install kdcproxy pyrad&lt;br /&gt;
&lt;br /&gt;
* The user account is named buildbot-worker and its homedir is /var/lib/buildbot/worker, so there is no need to create a &amp;quot;workers&amp;quot; subdirectory.  There appear to be no startup scripts, so add a user cron job &amp;quot;@reboot buildbot-worker start $HOME/NAME&amp;quot; to start the worker process on boot.&lt;br /&gt;
&lt;br /&gt;
==snapshot service==&lt;br /&gt;
&lt;br /&gt;
This service is probably no longer needed, but the setup details are covered here in case it becomes necessary to resurrect it.&lt;br /&gt;
&lt;br /&gt;
In the krbsnap home directory, create a subdirectory &amp;quot;snap&amp;quot; and copy the krbdev/gensnap script from krbdev-services into it.  Also create a keytab for the krbsnap principal in ~/snap/krbsnap.keytab.  Add the cron job to run gensnap from krbdev/krbsnap-crontab to the crontab for the krbsnap account.  (Do not install sync_gitsvn or its cron job; it is defunct.)&lt;br /&gt;
&lt;br /&gt;
The gensnap script updates a working copy for each branch, runs mkrel, and installs the results in krbsnap@aeneas.mit.edu:/var/ftp/pub/kerberos/dist/vaporware-r-us .  These snapshots are used by the old nightly build infrastructure (scripts in /mit/krbdev/testing), which has been supplanted by other CI systems.&lt;/div&gt;</summary>
		<author><name>Ghudson</name></author>	</entry>

	<entry>
		<id>https://k5wiki.kerberos.org/wiki?title=Buildbot_server_configuration&amp;diff=6049</id>
		<title>Buildbot server configuration</title>
		<link rel="alternate" type="text/html" href="https://k5wiki.kerberos.org/wiki?title=Buildbot_server_configuration&amp;diff=6049"/>
				<updated>2025-07-24T02:01:38Z</updated>
		
		<summary type="html">&lt;p&gt;Ghudson: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page contains notes on the setup of the MIT krb5 buildbot master and workers.  The buildbot master is hosted on krbdev-buildbot.mit.edu.  Workers are listed in machines.txt in the krbdev-services repository.&lt;br /&gt;
&lt;br /&gt;
==Operational notes==&lt;br /&gt;
&lt;br /&gt;
To force a new build on all workers, log into krbdev-buildbot.mit.edu, run &amp;quot;su -s /bin/bash - buildbot&amp;quot;, then run &amp;quot;buildbot sendchange -b master -m localhost:9989 -W yourusername@mit.edu&amp;quot; (or similarly for a different branch).&lt;br /&gt;
&lt;br /&gt;
==Packages==&lt;br /&gt;
&lt;br /&gt;
The python3-buildbot package is required for the buildbot master.  The git package is required for the krb5 repository mirror.&lt;br /&gt;
&lt;br /&gt;
Ubuntu 22.04 does not include the buildbot web interface, so it is necessary to install it using pip3:&lt;br /&gt;
&lt;br /&gt;
  apt install python-pip3&lt;br /&gt;
  pip3 install buildbot-www==3.4.0 buildbot-console-view==3.4.0 buildbot-grid-view==3.4.0 buildbot-waterfall-view==3.4.0&lt;br /&gt;
&lt;br /&gt;
The version &amp;quot;3.4.0&amp;quot; should match the system buildbot package version, which can be determined with &amp;quot;dpkg -l buildbot&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
==buildbot master setup==&lt;br /&gt;
&lt;br /&gt;
Run:&lt;br /&gt;
&lt;br /&gt;
  su -s /bin/bash - buildbot&lt;br /&gt;
  touch .k5login&lt;br /&gt;
  rmdir masters workers&lt;br /&gt;
  buildbot create-master -r master&lt;br /&gt;
&lt;br /&gt;
Install buildbot/master.cfg from krbdev-services into /var/lib/buildbot/master.  Copy /var/lib/buildbot/master/workers.py from the old server.  Make sure both files are owned by and readable by buildbot.  If it is necessary to reconstruct workers.py, has the form:&lt;br /&gt;
&lt;br /&gt;
  from buildbot.worker import Worker&lt;br /&gt;
  workers = [&lt;br /&gt;
      Worker('v09', '&amp;lt;password&amp;gt;', properties={'platform': 'amd64-u1204'}),&lt;br /&gt;
      ...&lt;br /&gt;
  ]&lt;br /&gt;
&lt;br /&gt;
The name and password must match the values used on the worker.  The platform is mostly arbitrary and will be used to construct builder entries.  Multiple workers can have the same platform.  The third argument may be omitted for workers that run special tasks (such as the documentation build) and aren't part of the regular platform builds.&lt;br /&gt;
&lt;br /&gt;
Copy over .ssh/authorized_keys from the old server's /var/lib/buildbot.  If it is necessary to reconstruct it, it must contain the ssh key for each worker entry (.ssh/id_rsa.pub from the buildbot account on the worker).&lt;br /&gt;
&lt;br /&gt;
As root, edit /etc/default/buildmaster and change the values so they read:&lt;br /&gt;
&lt;br /&gt;
  MASTER_ENABLED[1]=1&lt;br /&gt;
  MASTER_NAME[1]=&amp;quot;master&amp;quot;&lt;br /&gt;
  MASTER_USER[1]=&amp;quot;buildbot&amp;quot;&lt;br /&gt;
  MASTER_BASEDIR[1]=&amp;quot;/var/lib/buildbot/master&amp;quot;&lt;br /&gt;
  MASTER_OPTIONS[1]=&amp;quot;&amp;quot;&lt;br /&gt;
  MASTER_PREFIXCMD[1]=&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Run &amp;quot;service buildmaster restart&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Install a krbsnap keytab into /var/lib/buildbot, readable only by root.  Install buildbot/doc-update.sh from krbdev-services into /var/lib/buildbot.  Add the following cron job:&lt;br /&gt;
&lt;br /&gt;
  0 4 * * * /var/lib/buildbot/doc-update.sh&lt;br /&gt;
&lt;br /&gt;
==git mirror setup==&lt;br /&gt;
&lt;br /&gt;
The buildbot master host runs a mirror of the drugstore krb5 git repository, for access by workers and to send change notifications to the buildbot master.&lt;br /&gt;
&lt;br /&gt;
Create a krbsnap account using the uid of the Athena krbsnap user:&lt;br /&gt;
&lt;br /&gt;
  useradd -m -u 38160 -s /bin/bash krbsnap&lt;br /&gt;
&lt;br /&gt;
As krbsnap, create ~/.ssh and add the krbsnap key from /git/krb5.git/hooks/krbsnap_rsa_key.pub on drugstore.mit.edu to ~/.ssh/authorized_keys.  (This file may be managed by ops along with the .k5login file, and ops may have created the krbsnap account during provisioning.)&lt;br /&gt;
&lt;br /&gt;
As krbsnap, run:&lt;br /&gt;
&lt;br /&gt;
  mkdir ~/krb5.git&lt;br /&gt;
  cd ~/krb5.git&lt;br /&gt;
  git init --bare&lt;br /&gt;
&lt;br /&gt;
To populate the git repository, log into drugstore as root, &amp;quot;su -s /bin/bash - yourusername&amp;quot;, and run:&lt;br /&gt;
&lt;br /&gt;
  cd /git/krb5.git&lt;br /&gt;
  GIT_SSH=/git/krb5.git/hooks/ssh-as-krbsnap git push krbsnap&lt;br /&gt;
&lt;br /&gt;
Make sure that /git/krb5.git/config contains a remote named &amp;quot;krbsnap&amp;quot; for krbsnap@krbdev-buildbot.mit.edu, and that the [hooks] section contains an entry &amp;quot;push-to = krbsnap&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
As krbsnap, fetch the git_buildbot.py script ( https://raw.githubusercontent.com/buildbot/buildbot-contrib/master/master/contrib/git_buildbot.py ) into ~/krb5.git/hooks, and modify it to begin with &amp;quot;#!/usr/bin/python3&amp;quot;.  Make sure it is executable.  Run:&lt;br /&gt;
&lt;br /&gt;
  cd ~/krb5.git&lt;br /&gt;
  touch git-daemon-export-ok&lt;br /&gt;
  cd hooks&lt;br /&gt;
  ln -s git_buildbot.py post-receive&lt;br /&gt;
&lt;br /&gt;
As krbsnap, run &amp;quot;crontab -e&amp;quot; and add this entry:&lt;br /&gt;
&lt;br /&gt;
  @reboot git daemon --detach --base-path=$HOME&lt;br /&gt;
&lt;br /&gt;
Run the command by hand to start the daemon initially.&lt;br /&gt;
&lt;br /&gt;
==buildbot worker setup==&lt;br /&gt;
&lt;br /&gt;
For the Solaris buildbot worker, see [[Solaris_Build_Environment]] for platform-specific instructions.&lt;br /&gt;
&lt;br /&gt;
Install the buildbot worker software, using the python3-buildbot-worker package (buildbot-slave prior to Ubuntu 18.04) or the platform equivalent.&lt;br /&gt;
&lt;br /&gt;
Install the following Ubuntu packages: autoconf bison build-essential git keyutils ldap-utils libcmocka-dev libkeyutils-dev libldap2-dev liblmdb-dev libsasl2-dev libssl-dev libtool pkg-config python3-kdcproxy python3-pip&lt;br /&gt;
&lt;br /&gt;
Install the slapd package.  apt may ask for a master password twice; the value is unimportant and can be left blank.&lt;br /&gt;
&lt;br /&gt;
On Ubuntu 18.04 or later, install libresolv-wrapper.&lt;br /&gt;
&lt;br /&gt;
Run &amp;quot;pip3 install pyrad&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
(TBD: enumerate packages needed for documentation build worker.)&lt;br /&gt;
&lt;br /&gt;
If the platform package does not create a buildbot account, create one with a home directory.  Create an empty .k5login file in the buildbot home directory.  These instructions will assume that the buildbot home directory is /var/lib/buildbot.&lt;br /&gt;
&lt;br /&gt;
As the buildbot account (&amp;quot;su -s /bin/bash - buildbot&amp;quot;), generate a key using:&lt;br /&gt;
&lt;br /&gt;
  ssh-keygen -q -N &amp;quot;&amp;quot; -f .ssh/id_rsa -t rsa&lt;br /&gt;
&lt;br /&gt;
Add the contents of .ssh/id_rsa.pub to ~buildbot/.ssh/authorized_keys on krbdev-buildbot.mit.edu.&lt;br /&gt;
&lt;br /&gt;
Run &amp;quot;ssh -l buildbot krbdev-buildbot.mit.edu&amp;quot; to get the master host key into .ssh/known_hosts.  The correct host key fingerprint of the master can be obtained by running &amp;quot;ssh-keygen -l -E sha256 -f /etc/ssh/ssh_host_ecdsa_key.pub&amp;quot; on krbdev-buildbot.mit.edu (or perhaps ssh_host_rsa_key.pub or ssh_host_dsa_key.pub if the worker has an old ssh client).&lt;br /&gt;
&lt;br /&gt;
Create a &amp;quot;workers&amp;quot; directory in buildbot's home directory and run &amp;quot;buildbot-worker create-worker /var/lib/buildbot/workers/NAME 127.0.0.1:9989 NAME PASSWORD&amp;quot;, using the name and password from the workers.py entry for the worker.  Prior to Ubuntu 18.04, the command is &amp;quot;buildslave create-slave&amp;quot; and the subdirectory should be named &amp;quot;slaves&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Arrange for the buildslave process to be started on boot.  On Ubuntu 18.04, this is accomplished by editing /etc/default/buildbot-worker as root and setting:&lt;br /&gt;
&lt;br /&gt;
  WORKER_ENABLED[1]=1&lt;br /&gt;
  WORKER_NAME[1]=&amp;quot;NAME&amp;quot;&lt;br /&gt;
  WORKER_USER[1]=&amp;quot;buildbot&amp;quot;&lt;br /&gt;
  WORKER_BASEDIR[1]=&amp;quot;/var/lib/buildbot/workers/NAME&amp;quot;&lt;br /&gt;
  WORKER_OPTIONS[1]=&amp;quot;&amp;quot;&lt;br /&gt;
  WORKER_PREFIXCMD[1]=&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
On earlier versions of Ubuntu, the file is /etc/default/buildslave and each occurrence of &amp;quot;worker&amp;quot; is replaced with &amp;quot;slave&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Add a cron job for the buildbot account (run &amp;quot;crontab -e&amp;quot; as buildbot) to maintain the ssh tunnel to the master:&lt;br /&gt;
&lt;br /&gt;
  */5 *  *   *   *     exec ssh -oExitOnForwardFailure=yes -l buildbot -N -L9989:127.0.0.1:9989 krbdev-buildbot.mit.edu&lt;br /&gt;
&lt;br /&gt;
Run the command manually (backgrounded, without the &amp;quot;exec&amp;quot;) to start it for the current session.&lt;br /&gt;
&lt;br /&gt;
The worker which runs the documentation build needs the python3-lxml package, and either the python3-cheetah package (requires Ubuntu 18.10 or higher) or the python3-pip package and &amp;quot;pip3 install cheetah3&amp;quot; to be run.&lt;br /&gt;
&lt;br /&gt;
On RHEL workers there are several differences:&lt;br /&gt;
&lt;br /&gt;
* Enable EPEL with the following commands, substituting X with the RHEL version:&lt;br /&gt;
&lt;br /&gt;
  subscription-manager repos --enable codeready-builder-for-rhel-X-$(arch)-rpms&lt;br /&gt;
  dnf -y install https://dl.fedoraproject.org/pub/epel/epel-release-latest-X.noarch.rpm&lt;br /&gt;
&lt;br /&gt;
* Install necessary packages with:&lt;br /&gt;
&lt;br /&gt;
  dnf -y group install &amp;quot;Development Tools&amp;quot;&lt;br /&gt;
  dnf -y install buildbot-worker openldap-devel openldap-clients openldap-servers libcmocka-devel lmdb-devel cyrus-sasl-devel&lt;br /&gt;
  pip3 install kdcproxy pyrad&lt;br /&gt;
&lt;br /&gt;
* The user account is named buildbot-worker and its homedir is /var/lib/buildbot/worker.  There appear to be no startup scripts, so add a user cron job &amp;quot;@reboot buildbot-worker start $HOME/v08&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
==snapshot service==&lt;br /&gt;
&lt;br /&gt;
This service is probably no longer needed, but the setup details are covered here in case it becomes necessary to resurrect it.&lt;br /&gt;
&lt;br /&gt;
In the krbsnap home directory, create a subdirectory &amp;quot;snap&amp;quot; and copy the krbdev/gensnap script from krbdev-services into it.  Also create a keytab for the krbsnap principal in ~/snap/krbsnap.keytab.  Add the cron job to run gensnap from krbdev/krbsnap-crontab to the crontab for the krbsnap account.  (Do not install sync_gitsvn or its cron job; it is defunct.)&lt;br /&gt;
&lt;br /&gt;
The gensnap script updates a working copy for each branch, runs mkrel, and installs the results in krbsnap@aeneas.mit.edu:/var/ftp/pub/kerberos/dist/vaporware-r-us .  These snapshots are used by the old nightly build infrastructure (scripts in /mit/krbdev/testing), which has been supplanted by other CI systems.&lt;/div&gt;</summary>
		<author><name>Ghudson</name></author>	</entry>

	<entry>
		<id>https://k5wiki.kerberos.org/wiki?title=Buildbot_server_configuration&amp;diff=6048</id>
		<title>Buildbot server configuration</title>
		<link rel="alternate" type="text/html" href="https://k5wiki.kerberos.org/wiki?title=Buildbot_server_configuration&amp;diff=6048"/>
				<updated>2025-07-23T15:04:04Z</updated>
		
		<summary type="html">&lt;p&gt;Ghudson: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page contains notes on the setup of the MIT krb5 buildbot master and workers.  The buildbot master is hosted on krbdev-buildbot.mit.edu.  Workers are listed in machines.txt in the krbdev-services repository.&lt;br /&gt;
&lt;br /&gt;
==Operational notes==&lt;br /&gt;
&lt;br /&gt;
To force a new build on all workers, log into krbdev-buildbot.mit.edu, run &amp;quot;su -s /bin/bash - buildbot&amp;quot;, then run &amp;quot;buildbot sendchange -b master -m localhost:9989 -W yourusername@mit.edu&amp;quot; (or similarly for a different branch).&lt;br /&gt;
&lt;br /&gt;
==Packages==&lt;br /&gt;
&lt;br /&gt;
The python3-buildbot package is required for the buildbot master.  The git package is required for the krb5 repository mirror.&lt;br /&gt;
&lt;br /&gt;
Ubuntu 22.04 does not include the buildbot web interface, so it is necessary to install it using pip3:&lt;br /&gt;
&lt;br /&gt;
  apt install python-pip3&lt;br /&gt;
  pip3 install buildbot-www==3.4.0 buildbot-console-view==3.4.0 buildbot-grid-view==3.4.0 buildbot-waterfall-view==3.4.0&lt;br /&gt;
&lt;br /&gt;
The version &amp;quot;3.4.0&amp;quot; should match the system buildbot package version, which can be determined with &amp;quot;dpkg -l buildbot&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
==buildbot master setup==&lt;br /&gt;
&lt;br /&gt;
Run:&lt;br /&gt;
&lt;br /&gt;
  su -s /bin/bash - buildbot&lt;br /&gt;
  touch .k5login&lt;br /&gt;
  rmdir masters workers&lt;br /&gt;
  buildbot create-master -r master&lt;br /&gt;
&lt;br /&gt;
Install buildbot/master.cfg from krbdev-services into /var/lib/buildbot/master.  Copy /var/lib/buildbot/master/workers.py from the old server.  Make sure both files are owned by and readable by buildbot.  If it is necessary to reconstruct workers.py, has the form:&lt;br /&gt;
&lt;br /&gt;
  from buildbot.worker import Worker&lt;br /&gt;
  workers = [&lt;br /&gt;
      Worker('v09', '&amp;lt;password&amp;gt;', properties={'platform': 'amd64-u1204'}),&lt;br /&gt;
      ...&lt;br /&gt;
  ]&lt;br /&gt;
&lt;br /&gt;
The name and password must match the values used on the worker.  The platform is mostly arbitrary and will be used to construct builder entries.  Multiple workers can have the same platform.  The third argument may be omitted for workers that run special tasks (such as the documentation build) and aren't part of the regular platform builds.&lt;br /&gt;
&lt;br /&gt;
Copy over .ssh/authorized_keys from the old server's /var/lib/buildbot.  If it is necessary to reconstruct it, it must contain the ssh key for each worker entry (.ssh/id_rsa.pub from the buildbot account on the worker).&lt;br /&gt;
&lt;br /&gt;
As root, edit /etc/default/buildmaster and change the values so they read:&lt;br /&gt;
&lt;br /&gt;
  MASTER_ENABLED[1]=1&lt;br /&gt;
  MASTER_NAME[1]=&amp;quot;master&amp;quot;&lt;br /&gt;
  MASTER_USER[1]=&amp;quot;buildbot&amp;quot;&lt;br /&gt;
  MASTER_BASEDIR[1]=&amp;quot;/var/lib/buildbot/master&amp;quot;&lt;br /&gt;
  MASTER_OPTIONS[1]=&amp;quot;&amp;quot;&lt;br /&gt;
  MASTER_PREFIXCMD[1]=&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Run &amp;quot;service buildmaster restart&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Install a krbsnap keytab into /var/lib/buildbot, readable only by root.  Install buildbot/doc-update.sh from krbdev-services into /var/lib/buildbot.  Add the following cron job:&lt;br /&gt;
&lt;br /&gt;
  0 4 * * * /var/lib/buildbot/doc-update.sh&lt;br /&gt;
&lt;br /&gt;
==git mirror setup==&lt;br /&gt;
&lt;br /&gt;
The buildbot master host runs a mirror of the drugstore krb5 git repository, for access by workers and to send change notifications to the buildbot master.&lt;br /&gt;
&lt;br /&gt;
Create a krbsnap account using the uid of the Athena krbsnap user:&lt;br /&gt;
&lt;br /&gt;
  useradd -m -u 38160 -s /bin/bash krbsnap&lt;br /&gt;
&lt;br /&gt;
As krbsnap, create ~/.ssh and add the krbsnap key from /git/krb5.git/hooks/krbsnap_rsa_key.pub on drugstore.mit.edu to ~/.ssh/authorized_keys.  (This file may be managed by ops along with the .k5login file, and ops may have created the krbsnap account during provisioning.)&lt;br /&gt;
&lt;br /&gt;
As krbsnap, run:&lt;br /&gt;
&lt;br /&gt;
  mkdir ~/krb5.git&lt;br /&gt;
  cd ~/krb5.git&lt;br /&gt;
  git init --bare&lt;br /&gt;
&lt;br /&gt;
To populate the git repository, log into drugstore as root, &amp;quot;su -s /bin/bash - yourusername&amp;quot;, and run:&lt;br /&gt;
&lt;br /&gt;
  cd /git/krb5.git&lt;br /&gt;
  GIT_SSH=/git/krb5.git/hooks/ssh-as-krbsnap git push krbsnap&lt;br /&gt;
&lt;br /&gt;
Make sure that /git/krb5.git/config contains a remote named &amp;quot;krbsnap&amp;quot; for krbsnap@krbdev-buildbot.mit.edu, and that the [hooks] section contains an entry &amp;quot;push-to = krbsnap&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
As krbsnap, fetch the git_buildbot.py script ( https://raw.githubusercontent.com/buildbot/buildbot-contrib/master/master/contrib/git_buildbot.py ) into ~/krb5.git/hooks, and modify it to begin with &amp;quot;#!/usr/bin/python3&amp;quot;.  Make sure it is executable.  Run:&lt;br /&gt;
&lt;br /&gt;
  cd ~/krb5.git&lt;br /&gt;
  touch git-daemon-export-ok&lt;br /&gt;
  cd hooks&lt;br /&gt;
  ln -s git_buildbot.py post-receive&lt;br /&gt;
&lt;br /&gt;
As krbsnap, run &amp;quot;crontab -e&amp;quot; and add this entry:&lt;br /&gt;
&lt;br /&gt;
  @reboot git daemon --detach --base-path=$HOME&lt;br /&gt;
&lt;br /&gt;
Run the command by hand to start the daemon initially.&lt;br /&gt;
&lt;br /&gt;
==buildbot worker setup==&lt;br /&gt;
&lt;br /&gt;
For the Solaris buildbot worker, see [[Solaris_Build_Environment]] for platform-specific instructions.&lt;br /&gt;
&lt;br /&gt;
Install the buildbot worker software, using the python3-buildbot-worker package (buildbot-slave prior to Ubuntu 18.04) or the platform equivalent.&lt;br /&gt;
&lt;br /&gt;
Install the following Ubuntu packages: autoconf bison build-essential git keyutils ldap-utils libcmocka-dev libkeyutils-dev libldap2-dev liblmdb-dev libsasl2-dev libssl-dev libtool pkg-config python3-kdcproxy python3-pip&lt;br /&gt;
&lt;br /&gt;
Install the slapd package.  apt may ask for a master password twice; the value is unimportant and can be left blank.&lt;br /&gt;
&lt;br /&gt;
On Ubuntu 18.04 or later, install libresolv-wrapper.&lt;br /&gt;
&lt;br /&gt;
Run &amp;quot;pip3 install pyrad&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
(TBD: enumerate packages needed for documentation build worker.)&lt;br /&gt;
&lt;br /&gt;
If the platform package does not create a buildbot account, create one with a home directory.  Create an empty .k5login file in the buildbot home directory.  These instructions will assume that the buildbot home directory is /var/lib/buildbot.&lt;br /&gt;
&lt;br /&gt;
As the buildbot account (&amp;quot;su -s /bin/bash - buildbot&amp;quot;), generate a key using:&lt;br /&gt;
&lt;br /&gt;
  ssh-keygen -q -N &amp;quot;&amp;quot; -f .ssh/id_rsa -t rsa&lt;br /&gt;
&lt;br /&gt;
Add the contents of .ssh/id_rsa.pub to ~buildbot/.ssh/authorized_keys on krbdev-buildbot.mit.edu.&lt;br /&gt;
&lt;br /&gt;
Run &amp;quot;ssh -l buildbot krbdev-buildbot.mit.edu&amp;quot; to get the master host key into .ssh/known_hosts.  The correct host key fingerprint of the master can be obtained by running &amp;quot;ssh-keygen -l -E sha256 -f /etc/ssh/ssh_host_ecdsa_key.pub&amp;quot; on krbdev-buildbot.mit.edu (or perhaps ssh_host_rsa_key.pub or ssh_host_dsa_key.pub if the worker has an old ssh client).&lt;br /&gt;
&lt;br /&gt;
Create a &amp;quot;workers&amp;quot; directory in buildbot's home directory and run &amp;quot;buildbot-worker create-worker /var/lib/buildbot/workers/NAME 127.0.0.1:9989 NAME PASSWORD&amp;quot;, using the name and password from the workers.py entry for the worker.  Prior to Ubuntu 18.04, the command is &amp;quot;buildslave create-slave&amp;quot; and the subdirectory should be named &amp;quot;slaves&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Arrange for the buildslave process to be started on boot.  On Ubuntu 18.04, this is accomplished by editing /etc/default/buildbot-worker as root and setting:&lt;br /&gt;
&lt;br /&gt;
  WORKER_ENABLED[1]=1&lt;br /&gt;
  WORKER_NAME[1]=&amp;quot;NAME&amp;quot;&lt;br /&gt;
  WORKER_USER[1]=&amp;quot;buildbot&amp;quot;&lt;br /&gt;
  WORKER_BASEDIR[1]=&amp;quot;/var/lib/buildbot/workers/NAME&amp;quot;&lt;br /&gt;
  WORKER_OPTIONS[1]=&amp;quot;&amp;quot;&lt;br /&gt;
  WORKER_PREFIXCMD[1]=&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
On earlier versions of Ubuntu, the file is /etc/default/buildslave and each occurrence of &amp;quot;worker&amp;quot; is replaced with &amp;quot;slave&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Add a cron job for the buildbot account (run &amp;quot;crontab -e&amp;quot; as buildbot) to maintain the ssh tunnel to the master:&lt;br /&gt;
&lt;br /&gt;
  */5 *  *   *   *     exec ssh -oExitOnForwardFailure=yes -l buildbot -N -L9989:127.0.0.1:9989 krbdev-buildbot.mit.edu&lt;br /&gt;
&lt;br /&gt;
Run the command manually (backgrounded, without the &amp;quot;exec&amp;quot;) to start it for the current session.&lt;br /&gt;
&lt;br /&gt;
The worker which runs the documentation build needs the python3-lxml package, and either the python3-cheetah package (requires Ubuntu 18.10 or higher) or the python3-pip package and &amp;quot;pip3 install cheetah3&amp;quot; to be run.&lt;br /&gt;
&lt;br /&gt;
==snapshot service==&lt;br /&gt;
&lt;br /&gt;
This service is probably no longer needed, but the setup details are covered here in case it becomes necessary to resurrect it.&lt;br /&gt;
&lt;br /&gt;
In the krbsnap home directory, create a subdirectory &amp;quot;snap&amp;quot; and copy the krbdev/gensnap script from krbdev-services into it.  Also create a keytab for the krbsnap principal in ~/snap/krbsnap.keytab.  Add the cron job to run gensnap from krbdev/krbsnap-crontab to the crontab for the krbsnap account.  (Do not install sync_gitsvn or its cron job; it is defunct.)&lt;br /&gt;
&lt;br /&gt;
The gensnap script updates a working copy for each branch, runs mkrel, and installs the results in krbsnap@aeneas.mit.edu:/var/ftp/pub/kerberos/dist/vaporware-r-us .  These snapshots are used by the old nightly build infrastructure (scripts in /mit/krbdev/testing), which has been supplanted by other CI systems.&lt;/div&gt;</summary>
		<author><name>Ghudson</name></author>	</entry>

	<entry>
		<id>https://k5wiki.kerberos.org/wiki?title=Buildbot_server_configuration&amp;diff=6047</id>
		<title>Buildbot server configuration</title>
		<link rel="alternate" type="text/html" href="https://k5wiki.kerberos.org/wiki?title=Buildbot_server_configuration&amp;diff=6047"/>
				<updated>2025-07-23T15:00:23Z</updated>
		
		<summary type="html">&lt;p&gt;Ghudson: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page contains notes on the setup of the MIT krb5 buildbot master and workers.  The buildbot master is hosted on krbdev-buildbot.mit.edu.  Workers are listed in machines.txt in the krbdev-services repository.&lt;br /&gt;
&lt;br /&gt;
==Operational notes==&lt;br /&gt;
&lt;br /&gt;
To force a new build on all workers, log into krbdev-buildbot.mit.edu, run &amp;quot;su -s /bin/bash - buildbot&amp;quot;, then run &amp;quot;buildbot sendchange -b master -m localhost:9989 -W yourusername@mit.edu&amp;quot; (or similarly for a different branch).&lt;br /&gt;
&lt;br /&gt;
==Packages==&lt;br /&gt;
&lt;br /&gt;
The python3-buildbot package is required for the buildbot master.  The git package is required for the krb5 repository mirror.&lt;br /&gt;
&lt;br /&gt;
Ubuntu 22.04 does not include the buildbot web interface, so it is necessary to install it using pip3:&lt;br /&gt;
&lt;br /&gt;
  apt install python-pip3&lt;br /&gt;
  pip3 install buildbot-www==3.4.0 buildbot-console-view==3.4.0 buildbot-grid-view==3.4.0 buildbot-waterfall-view==3.4.0&lt;br /&gt;
&lt;br /&gt;
The version &amp;quot;3.4.0&amp;quot; should match the system buildbot package version, which can be determined with &amp;quot;dpkg -l buildbot&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
==buildbot master setup==&lt;br /&gt;
&lt;br /&gt;
Run:&lt;br /&gt;
&lt;br /&gt;
  su -s /bin/bash - buildbot&lt;br /&gt;
  touch .k5login&lt;br /&gt;
  rmdir masters workers&lt;br /&gt;
  buildbot create-master -r master&lt;br /&gt;
&lt;br /&gt;
Install buildbot/master.cfg from krbdev-services into /var/lib/buildbot/master.  Copy /var/lib/buildbot/master/workers.py from the old server.  Make sure both files are owned by and readable by buildbot.  If it is necessary to reconstruct workers.py, has the form:&lt;br /&gt;
&lt;br /&gt;
  from buildbot.worker import Worker&lt;br /&gt;
  workers = [&lt;br /&gt;
      Worker('v09', '&amp;lt;password&amp;gt;', properties={'platform': 'amd64-u1204'}),&lt;br /&gt;
      ...&lt;br /&gt;
  ]&lt;br /&gt;
&lt;br /&gt;
The name and password must match the values used on the worker.  The platform is mostly arbitrary and will be used to construct builder entries.  Multiple workers can have the same platform.  The third argument may be omitted for workers that run special tasks (such as the documentation build) and aren't part of the regular platform builds.&lt;br /&gt;
&lt;br /&gt;
Copy over .ssh/authorized_keys from the old server's /var/lib/buildbot.  If it is necessary to reconstruct it, it must contain the ssh key for each worker entry (.ssh/id_rsa.pub from the buildbot account on the worker).&lt;br /&gt;
&lt;br /&gt;
As root, edit /etc/default/buildmaster and change the values so they read:&lt;br /&gt;
&lt;br /&gt;
  MASTER_ENABLED[1]=1&lt;br /&gt;
  MASTER_NAME[1]=&amp;quot;master&amp;quot;&lt;br /&gt;
  MASTER_USER[1]=&amp;quot;buildbot&amp;quot;&lt;br /&gt;
  MASTER_BASEDIR[1]=&amp;quot;/var/lib/buildbot/master&amp;quot;&lt;br /&gt;
  MASTER_OPTIONS[1]=&amp;quot;&amp;quot;&lt;br /&gt;
  MASTER_PREFIXCMD[1]=&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Run &amp;quot;service buildmaster restart&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Install a krbsnap keytab into /var/lib/buildbot, readable only by root.  Install buildbot/doc-update.sh from krbdev-services into /var/lib/buildbot.  Add the following cron job:&lt;br /&gt;
&lt;br /&gt;
  0 4 * * * /var/lib/buildbot/doc-update.sh&lt;br /&gt;
&lt;br /&gt;
==git mirror setup==&lt;br /&gt;
&lt;br /&gt;
The buildbot master host runs a mirror of the drugstore krb5 git repository, for access by workers and to send change notifications to the buildbot master.&lt;br /&gt;
&lt;br /&gt;
Create a krbsnap account using the uid of the Athena krbsnap user:&lt;br /&gt;
&lt;br /&gt;
  useradd -m -u 38160 -s /bin/bash krbsnap&lt;br /&gt;
&lt;br /&gt;
As krbsnap, create ~/.ssh and add the krbsnap key from /git/krb5.git/hooks/krbsnap_rsa_key.pub on drugstore.mit.edu to ~/.ssh/authorized_keys.  (This file may be managed by ops along with the .k5login file, and ops may have created the krbsnap account during provisioning.)&lt;br /&gt;
&lt;br /&gt;
As krbsnap, run:&lt;br /&gt;
&lt;br /&gt;
  mkdir ~/krb5.git&lt;br /&gt;
  cd ~/krb5.git&lt;br /&gt;
  git init --bare&lt;br /&gt;
&lt;br /&gt;
To populate the git repository, log into drugstore as root, &amp;quot;su -s /bin/bash - yourusername&amp;quot;, and run:&lt;br /&gt;
&lt;br /&gt;
  cd /git/krb5.git&lt;br /&gt;
  GIT_SSH=/git/krb5.git/hooks/ssh-as-krbsnap git push krbsnap&lt;br /&gt;
&lt;br /&gt;
Make sure that /git/krb5.git/config contains a remote named &amp;quot;krbsnap&amp;quot; for krbsnap@krbdev-buildbot.mit.edu, and that the [hooks] section contains an entry &amp;quot;push-to = krbsnap&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
As krbsnap, fetch the git_buildbot.py script ( https://raw.githubusercontent.com/buildbot/buildbot-contrib/master/master/contrib/git_buildbot.py ) into ~/krb5.git/hooks, and modify it to begin with &amp;quot;#!/usr/bin/python3&amp;quot;.  Make sure it is executable.  Run:&lt;br /&gt;
&lt;br /&gt;
  cd ~/krb5.git&lt;br /&gt;
  touch git-daemon-export-ok&lt;br /&gt;
  cd hooks&lt;br /&gt;
  ln -s git_buildbot.py post-receive&lt;br /&gt;
&lt;br /&gt;
As krbsnap, run &amp;quot;crontab -e&amp;quot; and add this entry:&lt;br /&gt;
&lt;br /&gt;
  @reboot git daemon --detach --base-path=$HOME&lt;br /&gt;
&lt;br /&gt;
Run the command by hand to start the daemon initially.&lt;br /&gt;
&lt;br /&gt;
==buildbot worker setup==&lt;br /&gt;
&lt;br /&gt;
For the Solaris buildbot worker, see [[Solaris_Build_Environment]] for platform-specific instructions.&lt;br /&gt;
&lt;br /&gt;
Install the buildbot worker software, using the python3-buildbot-worker package (buildbot-slave prior to Ubuntu 18.04) or the platform equivalent.&lt;br /&gt;
&lt;br /&gt;
Install the following Ubuntu packages: autoconf bison build-essential git keyutils ldap-utils libcmocka-dev libkeyutils-dev libldap2-dev liblmdb-dev libsasl2-dev libssl-dev libtool pkg-config python3-kdcproxy python3-pip&lt;br /&gt;
&lt;br /&gt;
Install the slapd package.  apt may ask for a master password twice; the value is unimportant and can be left blank.&lt;br /&gt;
&lt;br /&gt;
On Ubuntu 18.04 or later, install libresolv-wrapper.&lt;br /&gt;
&lt;br /&gt;
Run &amp;quot;pip3 install pyrad&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
(TBD: enumerate packages needed for documentation build worker.)&lt;br /&gt;
&lt;br /&gt;
If the platform package does not create a buildbot account, create one with a home directory.  Create an empty .k5login file in the buildbot home directory.  These instructions will assume that the buildbot home directory is /var/lib/buildbot.&lt;br /&gt;
&lt;br /&gt;
As the buildbot account (&amp;quot;su -s /bin/bash - buildbot&amp;quot;), generate a key using:&lt;br /&gt;
&lt;br /&gt;
  ssh-keygen -q -N &amp;quot;&amp;quot; -f .ssh/id_rsa -t rsa&lt;br /&gt;
&lt;br /&gt;
Add the contents of .ssh/id_rsa.pub to ~buildbot/.ssh/authorized_keys on krbdev-buildbot.mit.edu.&lt;br /&gt;
&lt;br /&gt;
Run &amp;quot;ssh -l buildbot krbdev-buildbot.mit.edu&amp;quot; to get the master host key into .ssh/known_hosts.  The correct host key fingerprint of the master can be obtained by running &amp;quot;ssh-keygen -l -E sha256 -f /etc/ssh/ssh_host_ecdsa_key.pub&amp;quot; on krbdev-buildbot.mit.edu (or perhaps ssh_host_rsa_key.pub or ssh_host_dsa_key.pub if the worker has an old ssh client).&lt;br /&gt;
&lt;br /&gt;
Create a &amp;quot;workers&amp;quot; directory in buildbot's home directory and run &amp;quot;buildbot-worker create-worker /var/lib/buildbot/workers/NAME 127.0.0.1:9989 NAME PASSWORD&amp;quot;, using the name and password from the slaves.py entry for the worker.  Prior to Ubuntu 18.04, the command is &amp;quot;buildslave create-slave&amp;quot; and the subdirectory should be named &amp;quot;slaves&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Arrange for the buildslave process to be started on boot.  On Ubuntu 18.04, this is accomplished by editing /etc/default/buildbot-worker as root and setting:&lt;br /&gt;
&lt;br /&gt;
  WORKER_ENABLED[1]=1&lt;br /&gt;
  WORKER_NAME[1]=&amp;quot;NAME&amp;quot;&lt;br /&gt;
  WORKER_USER[1]=&amp;quot;buildbot&amp;quot;&lt;br /&gt;
  WORKER_BASEDIR[1]=&amp;quot;/var/lib/buildbot/workers/NAME&amp;quot;&lt;br /&gt;
  WORKER_OPTIONS[1]=&amp;quot;&amp;quot;&lt;br /&gt;
  WORKER_PREFIXCMD[1]=&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
On earlier versions of Ubuntu, the file is /etc/default/buildslave and each occurrence of &amp;quot;worker&amp;quot; is replaced with &amp;quot;slave&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Add a cron job for the buildbot account (run &amp;quot;crontab -e&amp;quot; as buildbot) to maintain the ssh tunnel to the master:&lt;br /&gt;
&lt;br /&gt;
  */5 *  *   *   *     exec ssh -oExitOnForwardFailure=yes -l buildbot -N -L9989:127.0.0.1:9989 krbdev-buildbot.mit.edu&lt;br /&gt;
&lt;br /&gt;
Run the command manually (backgrounded, without the &amp;quot;exec&amp;quot;) to start it for the current session.&lt;br /&gt;
&lt;br /&gt;
The worker which runs the documentation build needs the python3-lxml package, and either the python3-cheetah package (requires Ubuntu 18.10 or higher) or the python3-pip package and &amp;quot;pip3 install cheetah3&amp;quot; to be run.&lt;br /&gt;
&lt;br /&gt;
==snapshot service==&lt;br /&gt;
&lt;br /&gt;
This service is probably no longer needed, but the setup details are covered here in case it becomes necessary to resurrect it.&lt;br /&gt;
&lt;br /&gt;
In the krbsnap home directory, create a subdirectory &amp;quot;snap&amp;quot; and copy the krbdev/gensnap script from krbdev-services into it.  Also create a keytab for the krbsnap principal in ~/snap/krbsnap.keytab.  Add the cron job to run gensnap from krbdev/krbsnap-crontab to the crontab for the krbsnap account.  (Do not install sync_gitsvn or its cron job; it is defunct.)&lt;br /&gt;
&lt;br /&gt;
The gensnap script updates a working copy for each branch, runs mkrel, and installs the results in krbsnap@aeneas.mit.edu:/var/ftp/pub/kerberos/dist/vaporware-r-us .  These snapshots are used by the old nightly build infrastructure (scripts in /mit/krbdev/testing), which has been supplanted by other CI systems.&lt;/div&gt;</summary>
		<author><name>Ghudson</name></author>	</entry>

	<entry>
		<id>https://k5wiki.kerberos.org/wiki?title=Buildbot_server_configuration&amp;diff=6046</id>
		<title>Buildbot server configuration</title>
		<link rel="alternate" type="text/html" href="https://k5wiki.kerberos.org/wiki?title=Buildbot_server_configuration&amp;diff=6046"/>
				<updated>2025-07-22T23:04:32Z</updated>
		
		<summary type="html">&lt;p&gt;Ghudson: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page contains notes on the setup of the MIT krb5 buildbot master and workers.  The buildbot master is hosted on krbdev-buildbot.mit.edu.  Workers are listed in machines.txt in the krbdev-services repository.&lt;br /&gt;
&lt;br /&gt;
==Operational notes==&lt;br /&gt;
&lt;br /&gt;
To force a new build on all workers, log into krbdev-buildbot.mit.edu, run &amp;quot;su -s /bin/bash - buildbot&amp;quot;, then run &amp;quot;buildbot sendchange -b master -m localhost:9989 -W yourusername@mit.edu&amp;quot; (or similarly for a different branch).&lt;br /&gt;
&lt;br /&gt;
==Packages==&lt;br /&gt;
&lt;br /&gt;
The python3-buildbot package is required for the buildbot master.  The git package is required for the krb5 repository mirror.&lt;br /&gt;
&lt;br /&gt;
Ubuntu 22.04 does not include the buildbot web interface, so it is necessary to install it using pip3:&lt;br /&gt;
&lt;br /&gt;
  apt install python-pip3&lt;br /&gt;
  pip3 install buildbot-www==3.4.0 buildbot-console-view==3.4.0 buildbot-grid-view==3.4.0 buildbot-waterfall-view==3.4.0&lt;br /&gt;
&lt;br /&gt;
The version &amp;quot;3.4.0&amp;quot; should match the system buildbot package version, which can be determined with &amp;quot;dpkg -l buildbot&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
==buildbot master setup==&lt;br /&gt;
&lt;br /&gt;
Run:&lt;br /&gt;
&lt;br /&gt;
  su -s /bin/bash - buildbot&lt;br /&gt;
  touch .k5login&lt;br /&gt;
  rmdir masters workers&lt;br /&gt;
  buildbot create-master -r master&lt;br /&gt;
&lt;br /&gt;
Install buildbot/master.cfg from krbdev-services into /var/lib/buildbot/master.  Copy /var/lib/buildbot/master/workers.py from the old server.  Make sure both files are owned by and readable by buildbot.  If it is necessary to reconstruct workers.py, has the form:&lt;br /&gt;
&lt;br /&gt;
  from buildbot.worker import Worker&lt;br /&gt;
  workers = [&lt;br /&gt;
      Worker('v09', '&amp;lt;password&amp;gt;', properties={'platform': 'amd64-u1204'}),&lt;br /&gt;
      ...&lt;br /&gt;
  ]&lt;br /&gt;
&lt;br /&gt;
The name and password must match the values used on the worker.  The platform is mostly arbitrary and will be used to construct builder entries.  Multiple workers can have the same platform.  The third argument may be omitted for workers that run special tasks (such as the documentation build) and aren't part of the regular platform builds.&lt;br /&gt;
&lt;br /&gt;
Copy over .ssh/authorized_keys from the old server's /var/lib/buildbot.  If it is necessary to reconstruct it, it must contain the ssh key for each worker entry (.ssh/id_rsa.pub from the buildbot account on the worker).&lt;br /&gt;
&lt;br /&gt;
As root, edit /etc/default/buildmaster and change the values so they read:&lt;br /&gt;
&lt;br /&gt;
  MASTER_ENABLED[1]=1&lt;br /&gt;
  MASTER_NAME[1]=&amp;quot;master&amp;quot;&lt;br /&gt;
  MASTER_USER[1]=&amp;quot;buildbot&amp;quot;&lt;br /&gt;
  MASTER_BASEDIR[1]=&amp;quot;/var/lib/buildbot/master&amp;quot;&lt;br /&gt;
  MASTER_OPTIONS[1]=&amp;quot;&amp;quot;&lt;br /&gt;
  MASTER_PREFIXCMD[1]=&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Run &amp;quot;service buildmaster restart&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Install a krbsnap keytab into /var/lib/buildbot, readable only by root.  Install buildbot/doc-update.sh from krbdev-services into /var/lib/buildbot.  Add the following cron job:&lt;br /&gt;
&lt;br /&gt;
  0 4 * * * /var/lib/buildbot/doc-update.sh&lt;br /&gt;
&lt;br /&gt;
==git mirror setup==&lt;br /&gt;
&lt;br /&gt;
The buildbot master host runs a mirror of the drugstore krb5 git repository, for access by workers and to send change notifications to the buildbot master.&lt;br /&gt;
&lt;br /&gt;
Create a krbsnap account using the uid of the Athena krbsnap user:&lt;br /&gt;
&lt;br /&gt;
  useradd -m -u 38160 -s /bin/bash krbsnap&lt;br /&gt;
&lt;br /&gt;
As krbsnap, create ~/.ssh and add the krbsnap key from /git/krb5.git/hooks/krbsnap_rsa_key.pub on drugstore.mit.edu to ~/.ssh/authorized_keys.  (This file may be managed by ops along with the .k5login file, and ops may have created the krbsnap account during provisioning.)&lt;br /&gt;
&lt;br /&gt;
As krbsnap, run:&lt;br /&gt;
&lt;br /&gt;
  mkdir ~/krb5.git&lt;br /&gt;
  cd ~/krb5.git&lt;br /&gt;
  git init --bare&lt;br /&gt;
&lt;br /&gt;
To populate the git repository, log into drugstore as root, &amp;quot;su -s /bin/bash - yourusername&amp;quot;, and run:&lt;br /&gt;
&lt;br /&gt;
  cd /git/krb5.git&lt;br /&gt;
  GIT_SSH=/git/krb5.git/hooks/ssh-as-krbsnap git push krbsnap&lt;br /&gt;
&lt;br /&gt;
Make sure that /git/krb5.git/config contains a remote named &amp;quot;krbsnap&amp;quot; for krbsnap@krbdev-buildbot.mit.edu, and that the [hooks] section contains an entry &amp;quot;push-to = krbsnap&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
As krbsnap, fetch the git_buildbot.py script ( https://raw.githubusercontent.com/buildbot/buildbot-contrib/master/master/contrib/git_buildbot.py ) into ~/krb5.git/hooks, and modify it to begin with &amp;quot;#!/usr/bin/python3&amp;quot;.  Make sure it is executable.  Run:&lt;br /&gt;
&lt;br /&gt;
  cd ~/krb5.git&lt;br /&gt;
  touch git-daemon-export-ok&lt;br /&gt;
  cd hooks&lt;br /&gt;
  ln -s git_buildbot.py post-receive&lt;br /&gt;
&lt;br /&gt;
As krbsnap, run &amp;quot;crontab -e&amp;quot; and add this entry:&lt;br /&gt;
&lt;br /&gt;
  @reboot git daemon --detach --base-path=$HOME&lt;br /&gt;
&lt;br /&gt;
Run the command by hand to start the daemon initially.&lt;br /&gt;
&lt;br /&gt;
==buildbot worker setup==&lt;br /&gt;
&lt;br /&gt;
For the Solaris buildbot worker, see [[Solaris_Build_Environment]] for platform-specific instructions.&lt;br /&gt;
&lt;br /&gt;
Install the buildbot worker software, using the python3-buildbot-worker package (buildbot-slave prior to Ubuntu 18.04) or the platform equivalent.&lt;br /&gt;
&lt;br /&gt;
Install the following Ubuntu packages: autoconf bison build-essential git keyutils ldap-utils libcmocka-dev libkeyutils-dev libldap2-dev liblmdb-dev libsasl2-dev libssl-dev libtool pkg-config python3-kdcproxy python3-pip&lt;br /&gt;
&lt;br /&gt;
Install the slapd package.  apt may ask for a master password twice; the value is unimportant and can be left blank.&lt;br /&gt;
&lt;br /&gt;
On Ubuntu 18.04 or later, install libresolv-wrapper.&lt;br /&gt;
&lt;br /&gt;
Run &amp;quot;pip3 install pyrad&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
(TBD: enumerate packages needed for documentation build worker.)&lt;br /&gt;
&lt;br /&gt;
If the platform package does not create a buildbot account, create one with a home directory.  Create an empty .k5login file in the buildbot home directory.  These instructions will assume that the buildbot home directory is /var/lib/buildbot.&lt;br /&gt;
&lt;br /&gt;
As the buildbot account (&amp;quot;su -s /bin/bash - buildbot&amp;quot;), generate a key using:&lt;br /&gt;
&lt;br /&gt;
  ssh-keygen -q -N '' -f .ssh/id_rsa -t rsa&lt;br /&gt;
&lt;br /&gt;
Add the contents of .ssh/id_rsa.pub to ~buildbot/.ssh/authorized_keys on krbdev-buildbot.mit.edu.&lt;br /&gt;
&lt;br /&gt;
Run &amp;quot;ssh -l buildbot krbdev-buildbot.mit.edu&amp;quot; to get the master host key into .ssh/known_hosts.  The correct host key fingerprint of the master can be obtained by running &amp;quot;ssh-keygen -l -E sha256 -f /etc/ssh/ssh_host_ecdsa_key.pub&amp;quot; on krbdev-buildbot.mit.edu (or perhaps ssh_host_rsa_key.pub or ssh_host_dsa_key.pub if the worker has an old ssh client).&lt;br /&gt;
&lt;br /&gt;
Create a &amp;quot;workers&amp;quot; directory in buildbot's home directory and run &amp;quot;buildbot-worker create-worker /var/lib/buildbot/workers/NAME 127.0.0.1:9989 NAME PASSWORD&amp;quot;, using the name and password from the slaves.py entry for the worker.  Prior to Ubuntu 18.04, the command is &amp;quot;buildslave create-slave&amp;quot; and the subdirectory should be named &amp;quot;slaves&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Arrange for the buildslave process to be started on boot.  On Ubuntu 18.04, this is accomplished by editing /etc/default/buildbot-worker as root and setting:&lt;br /&gt;
&lt;br /&gt;
  WORKER_ENABLED[1]=1&lt;br /&gt;
  WORKER_NAME[1]=&amp;quot;NAME&amp;quot;&lt;br /&gt;
  WORKER_USER[1]=&amp;quot;buildbot&amp;quot;&lt;br /&gt;
  WORKER_BASEDIR[1]=&amp;quot;/var/lib/buildbot/workers/NAME&amp;quot;&lt;br /&gt;
  WORKER_OPTIONS[1]=&amp;quot;&amp;quot;&lt;br /&gt;
  WORKER_PREFIXCMD[1]=&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
On earlier versions of Ubuntu, the file is /etc/default/buildslave and each occurrence of &amp;quot;worker&amp;quot; is replaced with &amp;quot;slave&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Add a cron job for the buildbot account (run &amp;quot;crontab -e&amp;quot; as buildbot) to maintain the ssh tunnel to the master:&lt;br /&gt;
&lt;br /&gt;
  */5 *  *   *   *     exec ssh -oExitOnForwardFailure=yes -l buildbot -N -L9989:127.0.0.1:9989 krbdev-buildbot.mit.edu&lt;br /&gt;
&lt;br /&gt;
Run the command manually (backgrounded, without the &amp;quot;exec&amp;quot;) to start it for the current session.&lt;br /&gt;
&lt;br /&gt;
The worker which runs the documentation build needs the python3-lxml package, and either the python3-cheetah package (requires Ubuntu 18.10 or higher) or the python3-pip package and &amp;quot;pip3 install cheetah3&amp;quot; to be run.&lt;br /&gt;
&lt;br /&gt;
==snapshot service==&lt;br /&gt;
&lt;br /&gt;
This service is probably no longer needed, but the setup details are covered here in case it becomes necessary to resurrect it.&lt;br /&gt;
&lt;br /&gt;
In the krbsnap home directory, create a subdirectory &amp;quot;snap&amp;quot; and copy the krbdev/gensnap script from krbdev-services into it.  Also create a keytab for the krbsnap principal in ~/snap/krbsnap.keytab.  Add the cron job to run gensnap from krbdev/krbsnap-crontab to the crontab for the krbsnap account.  (Do not install sync_gitsvn or its cron job; it is defunct.)&lt;br /&gt;
&lt;br /&gt;
The gensnap script updates a working copy for each branch, runs mkrel, and installs the results in krbsnap@aeneas.mit.edu:/var/ftp/pub/kerberos/dist/vaporware-r-us .  These snapshots are used by the old nightly build infrastructure (scripts in /mit/krbdev/testing), which has been supplanted by other CI systems.&lt;/div&gt;</summary>
		<author><name>Ghudson</name></author>	</entry>

	<entry>
		<id>https://k5wiki.kerberos.org/wiki?title=RT_server_configuration&amp;diff=6045</id>
		<title>RT server configuration</title>
		<link rel="alternate" type="text/html" href="https://k5wiki.kerberos.org/wiki?title=RT_server_configuration&amp;diff=6045"/>
				<updated>2025-07-17T21:55:04Z</updated>
		
		<summary type="html">&lt;p&gt;Ghudson: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page contains notes on the setup of the MIT krb5 RT server. The current server is krbdev.mit.edu (canonical name kerborg-prod-app-1.mit.edu), which runs Ubuntu 20.04.&lt;br /&gt;
&lt;br /&gt;
==Packages==&lt;br /&gt;
&lt;br /&gt;
In Ubuntu 20.04, the request-tracker4 package contains a suitable version of RT.  This package will ask some questions at installation time:&lt;br /&gt;
&lt;br /&gt;
* RT site name: krbdev.mit.edu&lt;br /&gt;
* handle RT_SiteConfig.pm permissions: yes&lt;br /&gt;
* use dbconfig-common: no&lt;br /&gt;
&lt;br /&gt;
It should also ask you some questions about names; the result goes into /etc/request-tracker4/RT_SiteConfig.d/50-debconf.pm .  These settings will override the ones in our RT-SiteConfig.pm file; make sure they wind up with the same values, and that WebBaseURL is set to https://krbdev.mit.edu .  Use &amp;quot;dpkg-reconfigure request-tracker4&amp;quot; to set the values if necessary.&lt;br /&gt;
&lt;br /&gt;
The data in RT is stored in a PostgreSQL database.  The postgresql Ubuntu package will install the recommended version of PostgreSQL for the current Ubuntu version.&lt;br /&gt;
&lt;br /&gt;
The mail interface to RT is handled by Postfix, so the postfix package is required.  The libsendmail-pmilter-perl package is required for the custom milter script.&lt;br /&gt;
&lt;br /&gt;
The web front end to RT is an Apache2 web server, so the apache2 package is required.  RT uses a FastCGI server, so the libapache2-mod-fcgid package is required.&lt;br /&gt;
&lt;br /&gt;
The server host acts as an authoritative name server for the kerberos.org zone, so the bind9 package must be installed.&lt;br /&gt;
&lt;br /&gt;
The server hosts the authoritative git repository, so the git package must be installed.&lt;br /&gt;
&lt;br /&gt;
In sum, the following packages must be installed on the RT server:&lt;br /&gt;
&lt;br /&gt;
  apache2&lt;br /&gt;
  bind9&lt;br /&gt;
  git&lt;br /&gt;
  libapache2-mod-fcgid&lt;br /&gt;
  libsendmail-pmilter-perl&lt;br /&gt;
  perl&lt;br /&gt;
  perl-base&lt;br /&gt;
  postfix&lt;br /&gt;
  postgresql&lt;br /&gt;
  request-tracker4&lt;br /&gt;
&lt;br /&gt;
==User accounts==&lt;br /&gt;
&lt;br /&gt;
The postgresql package will create a postgres user account.&lt;br /&gt;
&lt;br /&gt;
The following user accounts and group entries must be created manually:&lt;br /&gt;
&lt;br /&gt;
* group rt&lt;br /&gt;
* user rtcvs: primary group rt, homedir /var/rt2, shell /bin/sh&lt;br /&gt;
* user rt: primary group rt, homedir /var/rt2, shell /bin/false&lt;br /&gt;
&lt;br /&gt;
These accounts could be created with:&lt;br /&gt;
&lt;br /&gt;
  groupadd -r rt&lt;br /&gt;
  useradd -r -g rt -d /var/rt2 rtcvs&lt;br /&gt;
  useradd -r -m -g rt -d /var/rt2 -s /bin/false rt&lt;br /&gt;
&lt;br /&gt;
Some of the above accounts may be created by ops during provisioning.  /var/rt2 and /var/rt2/.ssh must be owned by rtcvs or sshd will reject logins as rtcvs.&lt;br /&gt;
&lt;br /&gt;
For the authoritative repository, create a group named &amp;quot;krbwrite&amp;quot; and an account for each committer, with a root-owned home directory and git-shell configuration:&lt;br /&gt;
&lt;br /&gt;
    groupadd krbwrite&lt;br /&gt;
    # Repeat the following commands for each committer.&lt;br /&gt;
    useradd -u 3622 -s /usr/bin/git-shell -G krbwrite ghudson&lt;br /&gt;
    mkdir /home/ghudson&lt;br /&gt;
    mkdir /home/ghudson/git-shell-commands&lt;br /&gt;
    ln -s /git/krb5.git/hooks/krb5-rt-id /home/ghudson/git-shell-commands&lt;br /&gt;
&lt;br /&gt;
Create /var/rt2/bin and copy in the following scripts from the krbdev-services repository:&lt;br /&gt;
&lt;br /&gt;
  rt-scripts/rt-reserve-ticket&lt;br /&gt;
  rt-scripts/rtmilter.pl&lt;br /&gt;
  rt-scripts/krb5-daily.sh&lt;br /&gt;
  rt-cvs/rt-cvsgate&lt;br /&gt;
&lt;br /&gt;
The scripts and directory should be mode 755 and owned by user rt and group rt.&lt;br /&gt;
&lt;br /&gt;
/var/rt2 should contain an empty .k5login file, managed by ops.  It should contain a .ssh/authorized_keys file, managed by ops, containing the krbsnap key from hooks/krbsnap_rsa_key.pub in the authoritative repository.&lt;br /&gt;
&lt;br /&gt;
Create /var/psqlbackups (owned by root).&lt;br /&gt;
&lt;br /&gt;
The rt user account is not actually needed for the current RT installation, and the homedir name /var/rt2 is outdated.  The following references need to be taken into account when changing the user and group configuration:&lt;br /&gt;
&lt;br /&gt;
* Both the rt and rtcvs accounts have the homedir /var/rt2.&lt;br /&gt;
* krb5-daily.sh references the krbsnap.keytab file and dumps directory in /var/rt2.&lt;br /&gt;
* A root cron job runs krb5-daily.sh from /var/rt2.&lt;br /&gt;
* A root cron job runs rtmilter on boot from /var/rt2.&lt;br /&gt;
* The empty /var/rt2/.k5login file is managed by ops.&lt;br /&gt;
* The /var/rt2/.ssh/authorized_keys file is managed by ops.&lt;br /&gt;
* The authoritative krb5 git repository rt-ssh-cmd config value references the rtcvs user and /var/rt2/bin/rt-cvsgate.&lt;br /&gt;
* The authoritative krb5 git repository hooks/krb5-rt-id script references the rtcvs user and /var/rt2/bin/rt-reserve-ticket.  This script comes from the krbdev-services repository's githooks/krb5-rt-id.&lt;br /&gt;
* Some of the same references are present in the krbdev-services repository, but they aren't used.&lt;br /&gt;
&lt;br /&gt;
==RT setup==&lt;br /&gt;
&lt;br /&gt;
Install the RT_SiteConfig.pm file from the krbdev-services repository in /etc/request-tracker4.&lt;br /&gt;
&lt;br /&gt;
In root's crontab file (&amp;quot;crontab -e&amp;quot; as root), add the following to perform daily maintenance:&lt;br /&gt;
&lt;br /&gt;
  MAILTO=krbcore-hw@mit.edu&lt;br /&gt;
  0 3 * * * /usr/sbin/rt-clean-sessions&lt;br /&gt;
  0 4 * * * /var/rt2/bin/krb5-daily.sh&lt;br /&gt;
&lt;br /&gt;
==PostgreSQL configuration==&lt;br /&gt;
&lt;br /&gt;
Many PostgreSQL files live in directories specific to the PostgreSQL major and minor version, such as /etc/postgresql/8.3 for PostgreSQL 8.3.&lt;br /&gt;
&lt;br /&gt;
The Ubuntu postgresql package will create a &amp;quot;main&amp;quot; cluster with a configuration directory in /etc/postgresql/&amp;lt;version&amp;gt;/main.&lt;br /&gt;
&lt;br /&gt;
In /etc/postgresql/&amp;lt;version&amp;gt;/main/pg_ident.conf, add:&lt;br /&gt;
&lt;br /&gt;
  local		root		root&lt;br /&gt;
  local		root		postgres&lt;br /&gt;
  local		root		rt_user&lt;br /&gt;
  local		rt		rt_user&lt;br /&gt;
  local		rtcvs		rt_user&lt;br /&gt;
  local		postfix		rt_user&lt;br /&gt;
  local		nobody		rt_user&lt;br /&gt;
  local         www-data        rt_user&lt;br /&gt;
&lt;br /&gt;
(The entry for &amp;quot;rt&amp;quot; should no longer be needed, but is currently still present.)&lt;br /&gt;
&lt;br /&gt;
In /etc/postgresql/&amp;lt;version&amp;gt;/main/pg_hba.conf, find the line that reads &amp;quot;local all all peer&amp;quot; and add &amp;quot;map=local&amp;quot; to the end, so it reads &amp;quot;local all all peer map=local&amp;quot;.  Comment out the line that reads &amp;quot;local all postgres peer&amp;quot;, despite the warning not to disable it.  Run &amp;quot;service postgresql restart&amp;quot; to reread the affected files.  Run &amp;quot;psql -Upostgres --list&amp;quot; to verify that the identity map works.&lt;br /&gt;
&lt;br /&gt;
Run &amp;quot;createuser -Upostgres rt_user&amp;quot; to create the rt_user role.&lt;br /&gt;
&lt;br /&gt;
Run &amp;quot;/usr/sbin/rt-setup-database --action create&amp;quot; to create the database, then restore it from a backup with &amp;quot;zcat /path/to/dump.gz | psql -d rt4 -Upostgres&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==Postfix configuration==&lt;br /&gt;
&lt;br /&gt;
By default ops manages Postfix with Puppet.  This must be disabled by ops, and the Debian defaults restored by copying /usr/share/postfix/main.cf.debian to /etc/postfix/main.cf and /usr/share/postfix/master.cf.dist to /etc/postfix/master.cf.&lt;br /&gt;
&lt;br /&gt;
At the end of /etc/postfix/main.cf add:&lt;br /&gt;
&lt;br /&gt;
  myhostname = krbdev.mit.edu&lt;br /&gt;
  mydestination = krbdev.mit.edu, kerborg-prod-app-1.mit.edu, localhost.mit.edu, localhost&lt;br /&gt;
  &lt;br /&gt;
  # Suppress some headers to avoid leaking internal addresses to spammers.&lt;br /&gt;
  prepend_delivered_header =&lt;br /&gt;
  enable_original_recipient = no&lt;br /&gt;
  &lt;br /&gt;
  # RT header milter&lt;br /&gt;
  smtpd_milters = unix:private/milter&lt;br /&gt;
&lt;br /&gt;
Copy /etc/aliases from the old server.  To avoid aiding spammers, its contents are not reproduced here.  In particular, /etc/aliases contains an internal address corresponding to the membership of the krb5-bugs-incoming mailman list; revealing this address could allow spammers to bypass moderation of incoming bug reports.&lt;br /&gt;
&lt;br /&gt;
In root's crontab file (&amp;quot;crontab -e&amp;quot; as root):&lt;br /&gt;
&lt;br /&gt;
  @reboot /var/rt2/bin/rtmilter.pl /var/spool/postfix/private/milter&lt;br /&gt;
&lt;br /&gt;
Run the command by hand (backgrounded) to start the milter process before the next reboot.&lt;br /&gt;
&lt;br /&gt;
Run &amp;quot;newaliases&amp;quot; and &amp;quot;postfix reload&amp;quot; to pick up the changed configuration.&lt;br /&gt;
&lt;br /&gt;
Make sure rt@kerborg-prod-app-1.mit.edu and rt-comment@kerborg-prod-app-1.mit.edu are authorized as non-member senders at https://mailman.mit.edu:444/mailman/admin/krb5-bugs/privacy/sender .&lt;br /&gt;
&lt;br /&gt;
==Apache httpd configuration==&lt;br /&gt;
&lt;br /&gt;
Create /etc/apache2/ssl.crt and /etc/apache2/ssl.key.&lt;br /&gt;
&lt;br /&gt;
Copy /etc/apache2/ssl.key/server.key and /etc/apache2/ssl.crt/server.crt from the old server, or follow the instructions at http://kb.mit.edu/confluence/display/istcontrib/Obtaining+an+SSL+certificate+for+a+web+server to obtain a new one.  server.key and server.crt may be symlinks using whatever scheme seems convenient for renewing certificates every few years.&lt;br /&gt;
&lt;br /&gt;
Install /etc/apache2/ssl.crt/chain.crt from /mit/apache-ssl/certificates/InCommon-chain.crt.txt (requires tokens).  Cutting and pasting is effective for transferring certificates as they are represented as short text files.&lt;br /&gt;
&lt;br /&gt;
Install /etc/apache2/ssl.crt/clientCA.crt from /mit/apache-ssl/certificates/mitCAclient.pem (requires tokens).&lt;br /&gt;
&lt;br /&gt;
Install the rt.conf file from the krbdev-services repository as /etc/apache2/sites-available/rt.conf .&lt;br /&gt;
&lt;br /&gt;
Edit /etc/apache2/mods-available/proxy.conf and set:&lt;br /&gt;
&lt;br /&gt;
  ProxyVia On&lt;br /&gt;
&lt;br /&gt;
  ProxyPass /buildbot/ws ws://krbdev-buildbot.mit.edu:8010/ws&lt;br /&gt;
  ProxyPassReverse /buildbos/ws ws://krbdev-buildbot.mit.edu:8010/ws&lt;br /&gt;
  ProxyPass /buildbot/ http://krbdev-buildbot.mit.edu:8010/&lt;br /&gt;
  ProxyPassReverse /buildbot/ http://krbdev-buildbot.mit.edu:8010/&lt;br /&gt;
  &amp;lt;Proxy http://krbdev-buildbot.mit.edu:8010/*&amp;gt;&lt;br /&gt;
          Allow from all&lt;br /&gt;
  &amp;lt;/Proxy&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Edit /etc/apache2/ports.conf and add &amp;quot;Listen 444&amp;quot; in the ssl_module section after &amp;quot;Listen 443&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Clean out /var/www and install index.html and robots.txt from the krbdev-www directory of the krbdev-services repository.&lt;br /&gt;
&lt;br /&gt;
Run:&lt;br /&gt;
&lt;br /&gt;
  a2enmod ssl&lt;br /&gt;
  a2enmod userdir&lt;br /&gt;
  a2enmod rewrite&lt;br /&gt;
  a2enmod proxy_http&lt;br /&gt;
  a2enmod proxy_wstunnel&lt;br /&gt;
  a2dissite 000-default&lt;br /&gt;
  a2ensite rt&lt;br /&gt;
  service apache2 restart&lt;br /&gt;
&lt;br /&gt;
==Testing==&lt;br /&gt;
&lt;br /&gt;
Get a certificate for the new VM's real hostname and temporarily point /etc/apache2/ssl.crt/server.crt at it.&lt;br /&gt;
&lt;br /&gt;
In /etc/request-tracker4/RT_SiteConfig.pm, temporarily set @ReferrerWhitelist to use the real hostname instead of krbdev.mit.edu.&lt;br /&gt;
&lt;br /&gt;
Temporarily set emergency moderation on the krb5-bugs mailing list (at https://mailman.mit.edu:444/mailman/admin/krb5-bugs/general ) to ensure that mail sent to that list as the result of testing is caught in the moderation queue.&lt;br /&gt;
&lt;br /&gt;
Verify that RT displays at https://realhostname/rt and tickets can be accessed.  Verify that https://realhostname:444/ works and that a new ticket can be created.  Respond to the ticket via email and verify that the response is stored in the ticket.&lt;br /&gt;
&lt;br /&gt;
As root, run /var/rt2/bin/krb5-daily.sh and verify that a dump file appears in /var/psqlbackups.&lt;br /&gt;
&lt;br /&gt;
As rtcvs (&amp;quot;su -s /bin/bash - rtcvs&amp;quot;), run /var/rt2/bin/rt-reserve-ticket and verify that a ticket number is printed.&lt;br /&gt;
&lt;br /&gt;
To test rt-cvsgate, create a test message in /tmp/testmsg like so:&lt;br /&gt;
&lt;br /&gt;
  ticket: new&lt;br /&gt;
  id: NNNN (use the ticket number printed by rt-reserve-ticket above)&lt;br /&gt;
  subject: rt-cvsgate test&lt;br /&gt;
  tags: pullup&lt;br /&gt;
&lt;br /&gt;
  test commit message&lt;br /&gt;
&lt;br /&gt;
As rtcvs, run &amp;quot;/var/rt2/bin/rt-cvsgate ''username'' &amp;lt; /tmp/testmsg&amp;quot;, where ''username'' is an authorized user.&lt;br /&gt;
&lt;br /&gt;
Undo the temporary changes and restore the database from a dump file.&lt;br /&gt;
&lt;br /&gt;
==BIND configuration==&lt;br /&gt;
&lt;br /&gt;
The bind9 configuration files can be found in krbdev-services under bind. They should be installed under /etc/bind. &amp;quot;rndc reload&amp;quot; will restart the runing named with the changed configuration. If it is necessary to edit any of the zone files, be sure to update the serial number in the SOA record to the current date followed by &amp;quot;00&amp;quot; (or &amp;quot;01&amp;quot; etc. for successive edits in the same day).&lt;br /&gt;
&lt;br /&gt;
If the IP address if kerberos.org needs to be changed, the glue record at hover.com must be updated. In the current Hover UI, glue records can be found under &amp;quot;advanced&amp;quot;. The transfer lock on the domain must be temporarily disabled (via the Overview screen) to update glue records.&lt;br /&gt;
&lt;br /&gt;
==Git repository==&lt;br /&gt;
&lt;br /&gt;
The authoritative krb5 git repository lives in /git/krb5.git.  If this repository needs to be reconstructed from another mirror of the repository, install the hooks from the githooks directory of krbdev-services, add the krbsnap private and public SSH key to the hooks directory, and run the git configuration commands from gitconvert/krb5-convert.sh in krbdev-services.&lt;br /&gt;
&lt;br /&gt;
The authoritative krbdev-services repository lives in /git/krbdev-services.git.&lt;/div&gt;</summary>
		<author><name>Ghudson</name></author>	</entry>

	<entry>
		<id>https://k5wiki.kerberos.org/wiki?title=Buildbot_server_configuration&amp;diff=6044</id>
		<title>Buildbot server configuration</title>
		<link rel="alternate" type="text/html" href="https://k5wiki.kerberos.org/wiki?title=Buildbot_server_configuration&amp;diff=6044"/>
				<updated>2025-07-10T22:24:10Z</updated>
		
		<summary type="html">&lt;p&gt;Ghudson: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page contains notes on the setup of the MIT krb5 buildbot master and workers.  The buildbot master is hosted on krbdev-buildbot.mit.edu.  Workers are listed in machines.txt in the krbdev-services repository.&lt;br /&gt;
&lt;br /&gt;
==Operational notes==&lt;br /&gt;
&lt;br /&gt;
To force a new build on all workers, log into krbdev-buildbot.mit.edu, run &amp;quot;su -s /bin/bash - buildbot&amp;quot;, then run &amp;quot;buildbot sendchange -b master -m localhost:9989 -W yourusername@mit.edu&amp;quot; (or similarly for a different branch).&lt;br /&gt;
&lt;br /&gt;
==Packages==&lt;br /&gt;
&lt;br /&gt;
The python3-buildbot package is required for the buildbot master.  The git package is required for the krb5 repository mirror.&lt;br /&gt;
&lt;br /&gt;
Ubuntu 22.04 does not include the buildbot web interface, so it is necessary to install it using pip3:&lt;br /&gt;
&lt;br /&gt;
  apt install python-pip3&lt;br /&gt;
  pip3 install buildbot-www==3.4.0 buildbot-console-view==3.4.0 buildbot-grid-view==3.4.0 buildbot-waterfall-view==3.4.0&lt;br /&gt;
&lt;br /&gt;
The version &amp;quot;3.4.0&amp;quot; should match the system buildbot package version, which can be determined with &amp;quot;dpkg -l buildbot&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
==buildbot master setup==&lt;br /&gt;
&lt;br /&gt;
Run:&lt;br /&gt;
&lt;br /&gt;
  su -s /bin/bash - buildbot&lt;br /&gt;
  touch .k5login&lt;br /&gt;
  rmdir masters workers&lt;br /&gt;
  buildbot create-master -r master&lt;br /&gt;
&lt;br /&gt;
Install buildbot/master.cfg from krbdev-services into /var/lib/buildbot/master.  Copy /var/lib/buildbot/master/workers.py from the old server.  Make sure both files are owned by and readable by buildbot.  If it is necessary to reconstruct workers.py, has the form:&lt;br /&gt;
&lt;br /&gt;
  from buildbot.worker import Worker&lt;br /&gt;
  workers = [&lt;br /&gt;
      Worker('v09', '&amp;lt;password&amp;gt;', properties={'platform': 'amd64-u1204'}),&lt;br /&gt;
      ...&lt;br /&gt;
  ]&lt;br /&gt;
&lt;br /&gt;
The name and password must match the values used on the worker.  The platform is mostly arbitrary and will be used to construct builder entries.  Multiple workers can have the same platform.  The third argument may be omitted for workers that run special tasks (such as the documentation build) and aren't part of the regular platform builds.&lt;br /&gt;
&lt;br /&gt;
Copy over .ssh/authorized_keys from the old server's /var/lib/buildbot.  If it is necessary to reconstruct it, it must contain the ssh key for each worker entry (.ssh/id_rsa.pub from the buildbot account on the worker).&lt;br /&gt;
&lt;br /&gt;
As root, edit /etc/default/buildmaster and change the values so they read:&lt;br /&gt;
&lt;br /&gt;
  MASTER_ENABLED[1]=1&lt;br /&gt;
  MASTER_NAME[1]=&amp;quot;master&amp;quot;&lt;br /&gt;
  MASTER_USER[1]=&amp;quot;buildbot&amp;quot;&lt;br /&gt;
  MASTER_BASEDIR[1]=&amp;quot;/var/lib/buildbot/master&amp;quot;&lt;br /&gt;
  MASTER_OPTIONS[1]=&amp;quot;&amp;quot;&lt;br /&gt;
  MASTER_PREFIXCMD[1]=&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Run &amp;quot;service buildmaster restart&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Install a krbsnap keytab into /var/lib/buildbot, readable only by root.  Install buildbot/doc-update.sh from krbdev-services into /var/lib/buildbot.  Add the following cron job:&lt;br /&gt;
&lt;br /&gt;
  0 4 * * * /var/lib/buildbot/doc-update.sh&lt;br /&gt;
&lt;br /&gt;
==git mirror setup==&lt;br /&gt;
&lt;br /&gt;
The buildbot master host runs a mirror of the drugstore krb5 git repository, for access by workers and to send change notifications to the buildbot master.&lt;br /&gt;
&lt;br /&gt;
Create a krbsnap account using the uid of the Athena krbsnap user:&lt;br /&gt;
&lt;br /&gt;
  useradd -m -u 38160 -s /bin/bash krbsnap&lt;br /&gt;
&lt;br /&gt;
As krbsnap, create ~/.ssh and add the krbsnap key from /git/krb5.git/hooks/krbsnap_rsa_key.pub on drugstore.mit.edu to ~/.ssh/authorized_keys.  (This file may be managed by ops along with the .k5login file, and ops may have created the krbsnap account during provisioning.)&lt;br /&gt;
&lt;br /&gt;
As krbsnap, run:&lt;br /&gt;
&lt;br /&gt;
  mkdir ~/krb5.git&lt;br /&gt;
  cd ~/krb5.git&lt;br /&gt;
  git init --bare&lt;br /&gt;
&lt;br /&gt;
To populate the git repository, log into drugstore as root, &amp;quot;su -s /bin/bash - yourusername&amp;quot;, and run:&lt;br /&gt;
&lt;br /&gt;
  cd /git/krb5.git&lt;br /&gt;
  GIT_SSH=/git/krb5.git/hooks/ssh-as-krbsnap git push krbsnap&lt;br /&gt;
&lt;br /&gt;
Make sure that /git/krb5.git/config contains a remote named &amp;quot;krbsnap&amp;quot; for krbsnap@krbdev-buildbot.mit.edu, and that the [hooks] section contains an entry &amp;quot;push-to = krbsnap&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
As krbsnap, fetch the git_buildbot.py script ( https://raw.githubusercontent.com/buildbot/buildbot-contrib/master/master/contrib/git_buildbot.py ) into ~/krb5.git/hooks, and modify it to begin with &amp;quot;#!/usr/bin/python3&amp;quot;.  Make sure it is executable.  Run:&lt;br /&gt;
&lt;br /&gt;
  cd ~/krb5.git&lt;br /&gt;
  touch git-daemon-export-ok&lt;br /&gt;
  cd hooks&lt;br /&gt;
  ln -s git_buildbot.py post-receive&lt;br /&gt;
&lt;br /&gt;
As krbsnap, run &amp;quot;crontab -e&amp;quot; and add this entry:&lt;br /&gt;
&lt;br /&gt;
  @reboot git daemon --detach --base-path=$HOME&lt;br /&gt;
&lt;br /&gt;
Run the command by hand to start the daemon initially.&lt;br /&gt;
&lt;br /&gt;
==buildbot worker setup==&lt;br /&gt;
&lt;br /&gt;
For the Solaris buildbot worker, see [[Solaris_Build_Environment]] for platform-specific instructions.&lt;br /&gt;
&lt;br /&gt;
Install the buildbot worker software, using the python3-buildbot-worker package (buildbot-slave prior to Ubuntu 18.04) or the platform equivalent.&lt;br /&gt;
&lt;br /&gt;
Install the following Ubuntu packages: autoconf bison build-essential dejagnu git keyutils ldap-utils libcmocka-dev libkeyutils-dev libldap2-dev liblmdb-dev libsasl2-dev libssl-dev libtool pkg-config python3-kdcproxy python3-pip tcl-dev&lt;br /&gt;
&lt;br /&gt;
Install the slapd package.  apt may ask for a master password twice; the value is unimportant and can be left blank.&lt;br /&gt;
&lt;br /&gt;
On Ubuntu 18.04 or later, install libresolv-wrapper.&lt;br /&gt;
&lt;br /&gt;
Run &amp;quot;pip3 install pyrad&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
(TBD: enumerate packages needed for documentation build worker.)&lt;br /&gt;
&lt;br /&gt;
If the platform package does not create a buildbot account, create one with a home directory.  Create an empty .k5login file in the buildbot home directory.  These instructions will assume that the buildbot home directory is /var/lib/buildbot.&lt;br /&gt;
&lt;br /&gt;
As the buildbot account (&amp;quot;su -s /bin/bash - buildbot&amp;quot;), generate a key using:&lt;br /&gt;
&lt;br /&gt;
  ssh-keygen -q -N '' -f .ssh/id_rsa -t rsa&lt;br /&gt;
&lt;br /&gt;
Add the contents of .ssh/id_rsa.pub to ~buildbot/.ssh/authorized_keys on krbdev-buildbot.mit.edu.&lt;br /&gt;
&lt;br /&gt;
Run &amp;quot;ssh -l buildbot krbdev-buildbot.mit.edu&amp;quot; to get the master host key into .ssh/known_hosts.  The correct host key fingerprint of the master can be obtained by running &amp;quot;ssh-keygen -l -E sha256 -f /etc/ssh/ssh_host_ecdsa_key.pub&amp;quot; on krbdev-buildbot.mit.edu (or perhaps ssh_host_rsa_key.pub or ssh_host_dsa_key.pub if the worker has an old ssh client).&lt;br /&gt;
&lt;br /&gt;
Create a &amp;quot;workers&amp;quot; directory in buildbot's home directory and run &amp;quot;buildbot-worker create-worker /var/lib/buildbot/workers/NAME 127.0.0.1:9989 NAME PASSWORD&amp;quot;, using the name and password from the slaves.py entry for the worker.  Prior to Ubuntu 18.04, the command is &amp;quot;buildslave create-slave&amp;quot; and the subdirectory should be named &amp;quot;slaves&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Arrange for the buildslave process to be started on boot.  On Ubuntu 18.04, this is accomplished by editing /etc/default/buildbot-worker as root and setting:&lt;br /&gt;
&lt;br /&gt;
  WORKER_ENABLED[1]=1&lt;br /&gt;
  WORKER_NAME[1]=&amp;quot;NAME&amp;quot;&lt;br /&gt;
  WORKER_USER[1]=&amp;quot;buildbot&amp;quot;&lt;br /&gt;
  WORKER_BASEDIR[1]=&amp;quot;/var/lib/buildbot/workers/NAME&amp;quot;&lt;br /&gt;
  WORKER_OPTIONS[1]=&amp;quot;&amp;quot;&lt;br /&gt;
  WORKER_PREFIXCMD[1]=&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
On earlier versions of Ubuntu, the file is /etc/default/buildslave and each occurrence of &amp;quot;worker&amp;quot; is replaced with &amp;quot;slave&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Add a cron job for the buildbot account (run &amp;quot;crontab -e&amp;quot; as buildbot) to maintain the ssh tunnel to the master:&lt;br /&gt;
&lt;br /&gt;
  */5 *  *   *   *     exec ssh -oExitOnForwardFailure=yes -l buildbot -N -L9989:127.0.0.1:9989 krbdev-buildbot.mit.edu&lt;br /&gt;
&lt;br /&gt;
Run the command manually (backgrounded, without the &amp;quot;exec&amp;quot;) to start it for the current session.&lt;br /&gt;
&lt;br /&gt;
The worker which runs the documentation build needs the python3-lxml package, and either the python3-cheetah package (requires Ubuntu 18.10 or higher) or the python3-pip package and &amp;quot;pip3 install cheetah3&amp;quot; to be run.&lt;br /&gt;
&lt;br /&gt;
==snapshot service==&lt;br /&gt;
&lt;br /&gt;
This service is probably no longer needed, but the setup details are covered here in case it becomes necessary to resurrect it.&lt;br /&gt;
&lt;br /&gt;
In the krbsnap home directory, create a subdirectory &amp;quot;snap&amp;quot; and copy the krbdev/gensnap script from krbdev-services into it.  Also create a keytab for the krbsnap principal in ~/snap/krbsnap.keytab.  Add the cron job to run gensnap from krbdev/krbsnap-crontab to the crontab for the krbsnap account.  (Do not install sync_gitsvn or its cron job; it is defunct.)&lt;br /&gt;
&lt;br /&gt;
The gensnap script updates a working copy for each branch, runs mkrel, and installs the results in krbsnap@aeneas.mit.edu:/var/ftp/pub/kerberos/dist/vaporware-r-us .  These snapshots are used by the old nightly build infrastructure (scripts in /mit/krbdev/testing), which has been supplanted by other CI systems.&lt;/div&gt;</summary>
		<author><name>Ghudson</name></author>	</entry>

	<entry>
		<id>https://k5wiki.kerberos.org/wiki?title=Kerberos_for_Windows_(KfW)_Build_Environment&amp;diff=6043</id>
		<title>Kerberos for Windows (KfW) Build Environment</title>
		<link rel="alternate" type="text/html" href="https://k5wiki.kerberos.org/wiki?title=Kerberos_for_Windows_(KfW)_Build_Environment&amp;diff=6043"/>
				<updated>2025-06-26T03:33:49Z</updated>
		
		<summary type="html">&lt;p&gt;Ghudson: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category: Kerberos for Windows]]&lt;br /&gt;
Directions for producing an environment in which to build&lt;br /&gt;
Kerberos for Windows version 4.2&lt;br /&gt;
&lt;br /&gt;
* Install 64-bit Windows 10.&lt;br /&gt;
&lt;br /&gt;
* Install Visual Studio 2017 Community.&lt;br /&gt;
** Check &amp;quot;Desktop development with C++&amp;quot;.&lt;br /&gt;
** Check &amp;quot;MFC and ATL support&amp;quot;.&lt;br /&gt;
** After installing, locate the Visual Studio 2017 menu under the start menu, and pin the x64 and x86 Native Tools Command Prompt entries to the task bar for e&lt;br /&gt;
&lt;br /&gt;
* Install the chocolatey package manager from https://chocolatey.org/install (by pasting the PowerShell command line into an administrative powershell).  Install the following packages:&lt;br /&gt;
&lt;br /&gt;
  choco install wixtoolset -y&lt;br /&gt;
  choco install strawberryperl -y&lt;br /&gt;
  choco install git -y -params '&amp;quot;/GitAndUnixToolsOnPath&amp;quot;'&lt;br /&gt;
  choco install emacs -y&lt;br /&gt;
  choco install windbg -y&lt;br /&gt;
&lt;br /&gt;
* Add wix to the path.&lt;br /&gt;
** search for &amp;quot;environment&amp;quot; and run &amp;quot;Edit the system environment variables&amp;quot;.&lt;br /&gt;
** Click &amp;quot;environment variables&amp;quot; (button at bottom)&lt;br /&gt;
** click on wix, copy value.&lt;br /&gt;
** click on path, click edit, click new, paste value and add &amp;quot;\bin&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Follow the instructions in src/windows/README to perform a build.  NODEBUG can be set in the environment (&amp;quot;set NODEBUG=1&amp;quot;) to avoid having to specify it on the nmake command line each time.  For MIT-specific builds, also &amp;quot;set MIT_INTERNAL=1&amp;quot; or specify it on the nmake command line when building the installer.&lt;br /&gt;
&lt;br /&gt;
Code signing:&lt;br /&gt;
&lt;br /&gt;
    signtool sign /v /d &amp;quot;MIT Kerberos for Windows installer&amp;quot; /a /fd sha256 /tr http://timestamp.comodoca.com /td sha256 foo.msi&lt;br /&gt;
&lt;br /&gt;
See also https://support.comodo.com/index.php?/Default/Knowledgebase/Article/View/68/7/&lt;br /&gt;
&lt;br /&gt;
More general KfW release engineering information at [[Kerberos for Windows Release Engineering]].&lt;/div&gt;</summary>
		<author><name>Ghudson</name></author>	</entry>

	<entry>
		<id>https://k5wiki.kerberos.org/wiki?title=Coding_style/Practices&amp;diff=6042</id>
		<title>Coding style/Practices</title>
		<link rel="alternate" type="text/html" href="https://k5wiki.kerberos.org/wiki?title=Coding_style/Practices&amp;diff=6042"/>
				<updated>2024-09-22T19:21:55Z</updated>
		
		<summary type="html">&lt;p&gt;Ghudson: /* Avoiding integer overflows */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__&lt;br /&gt;
==Quick Summary==&lt;br /&gt;
&lt;br /&gt;
* Avoid strcpy, strcat, sprintf, and *scanf.&lt;br /&gt;
* Use &amp;quot;goto cleanup&amp;quot; to ensure that resources are released on all function exit paths.&lt;br /&gt;
* Keep track of which pointers are owners and which are aliases; initialize owner pointers to NULL.&lt;br /&gt;
* Avoid creating structure instances containing a mix of owner and alias pointers.&lt;br /&gt;
* Check untrusted integer values before operating on them to avoid overflows.&lt;br /&gt;
* Use size_t for array indexes when the array is unbounded.  Use the same type as the bound when it is.&lt;br /&gt;
* Name output variables ending with &amp;quot;_out&amp;quot;.  Initialize them at the beginning of a function, then don't touch them until just before successful return.&lt;br /&gt;
* Don't use assignments as truth values except (perhaps) in a while loop.&lt;br /&gt;
* Use NULL for the null pointer and '\0' for the null character.  Don't use pointers or characters as truth values.&lt;br /&gt;
* Put braces around flow control statement bodies if they are more than one line long, and around any do-while loop.&lt;br /&gt;
* Try to keep preprocessor statements outside of function bodies.&lt;br /&gt;
* Avoid declarations of local variables in inner scope.&lt;br /&gt;
* Parenthesize (sparingly) to avoid C precedence confusion, especially when using bitwise operators.&lt;br /&gt;
* Use all-uppercase names for macros.&lt;br /&gt;
* Avoid stepping on reserved C namespaces.&lt;br /&gt;
* Use the krb5_ prefix for libkrb5 API functions, and the k5_ prefix for linker-visible internal functions.  Don't use a prefix for static functions.&lt;br /&gt;
* Don't use designated initializers or compound literals in code which is built on Windows.&lt;br /&gt;
* Don't use variable-length arrays or alloca().&lt;br /&gt;
* Avoid long or deeply nested function bodies.  Use helpers to limit function complexity.&lt;br /&gt;
* Function calls through pointers should look like &amp;quot;(*fp)(args)&amp;quot; or &amp;quot;vtable-&amp;gt;method(vars)&amp;quot;.&lt;br /&gt;
* Always declare function return types.  Use ANSI C-style function definitions.&lt;br /&gt;
* Don't pass or return structures by value in API functions.&lt;br /&gt;
* Precede functions with block comments describing what they do.&lt;br /&gt;
* Make your code warning-clean under the gcc warning flags used in our build system.&lt;br /&gt;
&lt;br /&gt;
== String Handling ==&lt;br /&gt;
&lt;br /&gt;
Code should not use any of the following functions: strcpy, strcat, sprintf, or any *scanf function.&lt;br /&gt;
&lt;br /&gt;
Dynamically allocated buffers are preferred to fixed-sized buffers.  When using dynamic buffers:&lt;br /&gt;
* Use strdup or asprintf for simple constructions.&lt;br /&gt;
* Use the k5buf module (k5-buf.h) for complex constructions.  If this is not desirable, strlcpy and strlcat are valid alternatives.&lt;br /&gt;
&lt;br /&gt;
Substitute versions of strlcpy, strlcat, and asprintf, for operating systems that don't supply them, are declared in k5-platform.h and defined in the support library (which practically everything in the tree links directly against).&lt;br /&gt;
&lt;br /&gt;
When using fixed-sized buffers:&lt;br /&gt;
* Use strlcpy for simple copies.&lt;br /&gt;
* Use snprintf for simple compound constructions.  Avoid using precision or field width specifiers in snprintf format strings.&lt;br /&gt;
* To check for truncation when using snprintf, use the following approach:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
result = snprintf(buffer, sizeof(buffer), &amp;quot;format string&amp;quot;, ...);&lt;br /&gt;
if (SNPRINTF_OVERFLOW(result, sizeof(buffer))&lt;br /&gt;
    handle_overflow_error;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The SNPRINTF_OVERFLOW macro is defined in k5-platform.h.&lt;br /&gt;
&lt;br /&gt;
=== Current conformance ===&lt;br /&gt;
&lt;br /&gt;
Existing code mostly conforms, with some exceptions.&lt;br /&gt;
&lt;br /&gt;
=== Rationale ===&lt;br /&gt;
&lt;br /&gt;
It is relatively common to audit a code base such as krb5 and flag all uses of strcpy and similar functions, even if they are used safely.  Verifying that the function is used safely requires manual inspection.  Using safer alternatives does not guarantee code safety, but does reduce the likelihood of a catastrophic buffer overflow vulnerability.&lt;br /&gt;
&lt;br /&gt;
In some compilation environments under Solaris, field widths and precisions are computed using screen columns rather than bytes.&lt;br /&gt;
&lt;br /&gt;
sprintf returns a signed integer; buffer sizes are typically size_t (which is an unsigned type).  Comparing the two directly will result in a warning from some compilers, and has unpredictable semantics depending on the relative widths of int and size_t.  Also, some sprintf implementations, such as the one in Solaris prior to version 10, return -1 on a buffer overflow, whereas the C99 behavior returns the number of bytes which would have been written to the string.  The SNPRINTF_OVERFLOW macro uses casts to address both issues.&lt;br /&gt;
&lt;br /&gt;
The k5buf module safely allows multi-step string construction within fixed-size or dynamic buffers without performing an error check on each append, and without pre-computing lengths.  Errors need only be checked when the resulting string needs to be read or handed off to another function.&lt;br /&gt;
&lt;br /&gt;
== Exception Handling ==&lt;br /&gt;
&lt;br /&gt;
If a function allocates several resources and has many exit paths, use the following general structure when possible:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
    krb5_error_code ret;&lt;br /&gt;
    char *ptr1 = NULL;&lt;br /&gt;
    krb5_blah *ptr2 = NULL;&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
    ret = another_function(...);&lt;br /&gt;
    if (ret)&lt;br /&gt;
        goto cleanup;&lt;br /&gt;
...&lt;br /&gt;
cleanup:&lt;br /&gt;
    free(ptr1);&lt;br /&gt;
    krb5_free_blah(ptr2);&lt;br /&gt;
    return ret;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(free() and krb5_free_foo() functions will both accept NULL as input and do nothing.)  Simpler functions may use simpler control structures, but do not get to the point of freeing the same resource in several different places within a function depending on the exit path.  Do not use multiple exit labels.&lt;br /&gt;
&lt;br /&gt;
Unless constrained by an API standard such as GSSAPI, functions which can fail should return a krb5_error_code.  Error codes are defined in com_err tables, usually located in src/lib/krb5/error_tables.&lt;br /&gt;
&lt;br /&gt;
Functions can also set extended error messages using krb5_set_error_message() (or, in dependencies of libkrb5, krb5int_set_error() on &amp;amp;context-&amp;gt;err).  Code should set extended error messages when an error condition is moderately likely to occur and the default string for the error code is insufficiently clear.  Avoid exposing function names and other implementation details in error messages.&lt;br /&gt;
&lt;br /&gt;
After ignoring or handling an error code, krb5_clear_error_message() (or krb5int_clear_error()) should be used to ensure that an extended error message is not applied erroneously to a later instance of the same error code.  This can be especially important in loops.&lt;br /&gt;
&lt;br /&gt;
=== Current conformance ===&lt;br /&gt;
&lt;br /&gt;
Existing code mostly conforms, with some exceptions.&lt;br /&gt;
&lt;br /&gt;
=== Rationale ===&lt;br /&gt;
&lt;br /&gt;
The &amp;quot;goto cleanup&amp;quot; flow control is the most reliable way to avoid resource leaks within the constraints of the krb5 code base.  Within libraries, the code base does not abort on memory allocation failure, so tends to have many exit paths within some functions.&lt;br /&gt;
&lt;br /&gt;
Extended error messages can provide invaluable information about error conditions, but merely serve to expand code if used mechanically.&lt;br /&gt;
&lt;br /&gt;
== Memory management ==&lt;br /&gt;
&lt;br /&gt;
An allocated object can have multiple pointers to it.  The pointer through which the object will eventually be freed is called the owner, and other pointers to the object are called aliases.  The owner may change over the lifetime of the object.&lt;br /&gt;
&lt;br /&gt;
When transferring ownership of a pointer (such as when returning an allocated value to a caller via an output parameter), null out the old owner pointer unless it is about to be destroyed or go out of scope.&lt;br /&gt;
&lt;br /&gt;
Avoid mixing owner pointers and aliases within a structure.  Create additional local variables to act as owner pointers when this situation occurs.&lt;br /&gt;
&lt;br /&gt;
Initialize variables containing owner pointers to NULL.  Free the pointed-to objects (unconditionally, when possible) in the function's cleanup handler.&lt;br /&gt;
&lt;br /&gt;
In some cases these rules may not be reasonable; for instance, temporary memory allocated within a loop body must be freed within the loop body, not in the cleanup handler.  Break these rules when necessary, but also make liberal use of helper functions to simplify memory management.&lt;br /&gt;
&lt;br /&gt;
=== Current conformance ===&lt;br /&gt;
&lt;br /&gt;
Newer code mostly conforms; older code does not.&lt;br /&gt;
&lt;br /&gt;
=== Rationale ===&lt;br /&gt;
&lt;br /&gt;
Following these rules makes it easier to verify that a function contains no memory leaks, no double frees, and no dereferences after frees.  These rules also keep memory management logic out of the core logic of a function, making it easier to understand.&lt;br /&gt;
&lt;br /&gt;
== Avoiding integer overflows ==&lt;br /&gt;
&lt;br /&gt;
When operating on integer values derived from untrusted input, care must be taken to prevent overflows.  When possible, compare suspect values without operating on them, not the results of operating on them:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/* This is safe if the invariant current &amp;lt;= len holds. */&lt;br /&gt;
if (offset &amp;gt; len - current)&lt;br /&gt;
   return EINVAL;&lt;br /&gt;
/* This is dangerous if offset is unbounded. */&lt;br /&gt;
if (current + offset &amp;gt; len)&lt;br /&gt;
    return EINVAL;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When indexing an array with no specified integer bound (such as a null-terminated array), use size_t for the index type.  When the array does have an integer bound, use the same type as the array bound.&lt;br /&gt;
&lt;br /&gt;
== Output parameter handling ==&lt;br /&gt;
&lt;br /&gt;
Output parameter names should typically end in &amp;quot;_out&amp;quot;.  Output parameters should typically be the last parameters to a function, with certain exceptions (such as context-like parameters).&lt;br /&gt;
&lt;br /&gt;
Avoid filling in a caller-allocated structure.  Instead, allocate the structure within the function and output a pointer to the structure.&lt;br /&gt;
&lt;br /&gt;
If a function has output parameters, their values should be defined in all cases, including on failure.  Most of the time, this means setting output parameters to NULL or zero at the beginning of the function, and not assigning real values to the output parameters until successful completion from the function is guaranteed.  A typical function with output parameters should look something like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
krb5_error_code&lt;br /&gt;
function_with_output_param(type *input_param, type *ptr_out)&lt;br /&gt;
{&lt;br /&gt;
  krb5_error_code ret;&lt;br /&gt;
  type *ptr = NULL;&lt;br /&gt;
&lt;br /&gt;
  *ptr_out = NULL;&lt;br /&gt;
&lt;br /&gt;
  stuff that can go wrong here, allocating ptr;&lt;br /&gt;
&lt;br /&gt;
  *ptr_out = ptr;&lt;br /&gt;
  ptr = NULL;&lt;br /&gt;
&lt;br /&gt;
cleanup:&lt;br /&gt;
  free_function(ptr);&lt;br /&gt;
  other cleanup code here;&lt;br /&gt;
  return ret;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Simple wrapper functions can delegate the initialization of output paremeters to the functions they wrap, ''unless'' they are invoking the wrapped function through a function pointer.&lt;br /&gt;
&lt;br /&gt;
=== Current conformance ===&lt;br /&gt;
&lt;br /&gt;
Existing code mostly does not conform.  Filling in caller-allocated structures is common (though far from universal) in the public libkrb5 API.&lt;br /&gt;
&lt;br /&gt;
=== Rationale ===&lt;br /&gt;
&lt;br /&gt;
Naming output parameters with an &amp;quot;_out&amp;quot; suffix helps readers easily identify them, and also makes it clearer when a resource's ownership is transferred to the caller.  Since output parameters are only used near the beginning and end of a function, the extra verbosity is not very burdensome.&lt;br /&gt;
&lt;br /&gt;
Initializing output parameters makes it clear to static analysis tools that the previous value of the output parameter will not be used.  If there happens to be a bug in the function such that it returns success but does not set output parameters, or in the caller such that it uses an output parameter even though the function returned failure, then the bug will result in predictable behavior (generally a NULL pointer dereference) with no security consequences beyond a denial of service attack.&lt;br /&gt;
&lt;br /&gt;
== Assignments as truth values ==&lt;br /&gt;
&lt;br /&gt;
Do not use assignments as truth values.  Rather than this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/* bad style */&lt;br /&gt;
if ((ret = krb5_foo()))&lt;br /&gt;
    /* ... */;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
do this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/* better style */&lt;br /&gt;
ret = krb5_foo();&lt;br /&gt;
if (ret)&lt;br /&gt;
    /* ... */;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Current conformance ===&lt;br /&gt;
&lt;br /&gt;
Existing code varies widely.&lt;br /&gt;
&lt;br /&gt;
=== Rationale ===&lt;br /&gt;
&lt;br /&gt;
This makes the code easier to read, and also makes it easier to use&lt;br /&gt;
debuggers.  It may be excusable to put assignments into the&lt;br /&gt;
conditional espression of a &amp;quot;while&amp;quot; statement, though, like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
while ((ch = getopt(argc, argv, &amp;quot;abn&amp;quot;)) != -1)&lt;br /&gt;
    /* ... */;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Using assignments as truth values in conditional expressions (&amp;quot;ternary expressions&amp;quot;) may make&lt;br /&gt;
code particularly impenetrable.&lt;br /&gt;
&lt;br /&gt;
== The many names of zero ==&lt;br /&gt;
&lt;br /&gt;
There are at least three types of &amp;quot;zero&amp;quot; known to C.  These are the&lt;br /&gt;
integer zero (0), the null pointer constant (NULL), and the character&lt;br /&gt;
constant zero ('\0').  Yes, these are usually all technically the&lt;br /&gt;
integer zero.  Use them in their correct contexts.  (Purists will&lt;br /&gt;
point out that 0 is a valid null pointer constant; still, do not use 0&lt;br /&gt;
to specify a null pointer constant.  For further unconfusion, read the&lt;br /&gt;
section on null pointer constants in the comp.lang.c FAQ.)  Do not use a lone&lt;br /&gt;
variable as a truth value unless it's of integer type.  Thus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
int i;&lt;br /&gt;
char *cp;&lt;br /&gt;
/* ... */&lt;br /&gt;
if (i)&lt;br /&gt;
    /* ... */;&lt;br /&gt;
if (cp != NULL) {&lt;br /&gt;
    while (*cp != '\0')&lt;br /&gt;
        /* ... */;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Do not cast uses of NULL unless you're calling a function with a&lt;br /&gt;
variable number of arguments, in which case you should cast it to to&lt;br /&gt;
the appropriate pointer type.  (NULL may be defined as 0, and an integer 0&lt;br /&gt;
may not be the same size in the argument list as a pointer on a 64-bit&lt;br /&gt;
platform.)  Likewise, do not cast the return value&lt;br /&gt;
from malloc() and friends; the prototype should declare them properly&lt;br /&gt;
as returning a void&amp;amp;nbsp;* and thus shouldn't require an explicit cast.&lt;br /&gt;
&lt;br /&gt;
In any case, reading the section in the C FAQ on null pointers is&lt;br /&gt;
highly recommended to remove confusion regarding null pointers in C,&lt;br /&gt;
since this is a subject of much confusion to even experienced&lt;br /&gt;
programmers.  In particular, if you do not understand why using&lt;br /&gt;
calloc() to allocate a struct that contains pointer members or why&lt;br /&gt;
calling memset() to initialize such a struct to all-bytes-zero is&lt;br /&gt;
wrong, reread that section again.  Due to the prevalence of this practice and the practical difficulties of eliminating it, our [[portability assumptions]] currently require that platforms represent null pointers as all-bits-zero.&lt;br /&gt;
&lt;br /&gt;
== Brace placement ==&lt;br /&gt;
&lt;br /&gt;
Control flow statements that have a single statement as their body&lt;br /&gt;
should nevertheless have braces around their bodies if the body is&lt;br /&gt;
more than one line long, especially in the case of stacked multiple&lt;br /&gt;
if-else clauses; use:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
if (x) {&lt;br /&gt;
    if (y)&lt;br /&gt;
        foo();&lt;br /&gt;
    else&lt;br /&gt;
        bar();&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
instead of:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/* bad style */&lt;br /&gt;
if (x)&lt;br /&gt;
    if (y)&lt;br /&gt;
        foo();&lt;br /&gt;
    else&lt;br /&gt;
        bar();&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
which, while legible to the compiler, may confuse human readers and&lt;br /&gt;
make the code less maintainable, especially if new branches get added&lt;br /&gt;
to any of the clauses.&lt;br /&gt;
&lt;br /&gt;
If you are writing a do-while loop that has only one statement in its&lt;br /&gt;
body, put braces around it anyway, since the while clause may be&lt;br /&gt;
mistaken for a while loop with an empty body.  Don't do this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/* bad style */&lt;br /&gt;
do&lt;br /&gt;
    foo();&lt;br /&gt;
while (x);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Instead, write this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/* better style */&lt;br /&gt;
do {&lt;br /&gt;
    foo();&lt;br /&gt;
} while (x);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Preprocessor conditionals ==&lt;br /&gt;
&lt;br /&gt;
Instead of scattering &amp;lt;code&amp;gt;#ifdef&amp;lt;/code&amp;gt; or other preprocessor conditionals throughout the code use preprocessor conditionals to control the definition of a function-like macro, or similar construct, which is used instead of embedded preprocessor conditionals in code.&lt;br /&gt;
&lt;br /&gt;
Instead of this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    do_something();&lt;br /&gt;
    /* bad style */&lt;br /&gt;
#ifdef DEBUG&lt;br /&gt;
    fprintf(stderr, &amp;quot;did something\n&amp;quot;);&lt;br /&gt;
#endif&lt;br /&gt;
    do_something_else();&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
do something more like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#ifdef DEBUG&lt;br /&gt;
#define DPRINTF(x) fprintf(stderr, x)&lt;br /&gt;
#else&lt;br /&gt;
#define DPRINTF(x)		/* empty */&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
/* ... */&lt;br /&gt;
&lt;br /&gt;
    do_something();&lt;br /&gt;
    /* better style */&lt;br /&gt;
    DPRINTF((&amp;quot;did something\n&amp;quot;));&lt;br /&gt;
    do_something_else();&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Do not intersperse conditional compilation&lt;br /&gt;
directives with control flow statements, as some combination of&lt;br /&gt;
&amp;lt;code&amp;gt;#define&amp;lt;/code&amp;gt;d symbols may result in statements getting eaten by dangling&lt;br /&gt;
bits of control flow statements.  When it is not possible to avoid&lt;br /&gt;
this questionable practice (you really should rewrite the relevant&lt;br /&gt;
code section), make use of redundant braces to make a compiler&lt;br /&gt;
error more likely than incorrect runtime behavior (such as&lt;br /&gt;
inadvertently providing someone with a root shell -- this has actually happened, long ago).&lt;br /&gt;
&lt;br /&gt;
Do not intersperse conditional compilation directives with control&lt;br /&gt;
flow statements in such a way that confuses emacs cc-mode.  Not only&lt;br /&gt;
does emacs get confused, but the code becomes more difficult to read&lt;br /&gt;
and maintain.  Therefore, avoid code like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    /* bad style */&lt;br /&gt;
    if (x) {&lt;br /&gt;
        f();&lt;br /&gt;
    }&lt;br /&gt;
#ifdef FOO&lt;br /&gt;
    else if (y) {&lt;br /&gt;
#else&lt;br /&gt;
    else {&lt;br /&gt;
#endif&lt;br /&gt;
        g();&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Put comments after conditional compilation directives such as &amp;quot;#else&amp;quot;&lt;br /&gt;
and &amp;quot;#endif&amp;quot;.  Make them correspond to the sense of the value that&lt;br /&gt;
controls the compilation of the section they are closing, i.e.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#ifdef FOO&lt;br /&gt;
/* ... */&lt;br /&gt;
#else /* !FOO */&lt;br /&gt;
/* ... */&lt;br /&gt;
#endif /* !FOO */&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Also, in the case of more complex conditional compilation directives,&lt;br /&gt;
write the comments like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#if defined(FOO) || defined(BAR)&lt;br /&gt;
/* ... */&lt;br /&gt;
#else /* !(defined(FOO) || defined(BAR)) */&lt;br /&gt;
/* ... */&lt;br /&gt;
#endif /* !(defined(FOO) || defined(BAR)) */&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Conformance ===&lt;br /&gt;
&lt;br /&gt;
Existing code mostly does not conform.&lt;br /&gt;
&lt;br /&gt;
=== Rationale ===&lt;br /&gt;
&lt;br /&gt;
Instances of &amp;quot;ifdef soup&amp;quot; make code more difficult to read, and make it more difficult to recognize bugs.  It also interferes with automated reformatting and analysis tools.&lt;br /&gt;
&lt;br /&gt;
== Local variables ==&lt;br /&gt;
&lt;br /&gt;
Do not declare variables in an inner scope, e.g. inside the compound&lt;br /&gt;
substatement of an if statement, unless the complexity of the code&lt;br /&gt;
really demands that the variables be declared that way.  In such&lt;br /&gt;
situations, the function could probably stand to be broken up into&lt;br /&gt;
smaller chunks anyway.  Do not declare variables in an inner scope&lt;br /&gt;
that shadow ones in an outer scope, since this leads to confusion.&lt;br /&gt;
Also, some debugging environments, such as gdb under Solaris, can't&lt;br /&gt;
see variables declared in an inner scope, so declaring such variables&lt;br /&gt;
will make maintenance more difficult as well.&lt;br /&gt;
&lt;br /&gt;
== Placement of parentheses ==&lt;br /&gt;
&lt;br /&gt;
Parenthesize expressions that may be confusing, particularly where C's&lt;br /&gt;
precedences are broken.  For example, the shift operators have lower&lt;br /&gt;
precedence than the +, -, *, /, and % operators.  Perhaps the most&lt;br /&gt;
familiar C precedence quirk is that equality and relational operators&lt;br /&gt;
are of higher precedence than assignment operators.  Less well known&lt;br /&gt;
is that the bitwise operators are of a lower precedence than equality&lt;br /&gt;
and relational operators.&lt;br /&gt;
&lt;br /&gt;
The sizeof operator takes either a unary expression or a parenthesized&lt;br /&gt;
type name.  It is not necessary to parenthesize the operand of sizeof&lt;br /&gt;
if it is applied to a unary expression, but still, always parenthesize&lt;br /&gt;
the operand of the sizeof operator.  The sizeof operator does not&lt;br /&gt;
evaluate its operand if it is a unary expression, so usages such as&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
s = sizeof(++foo);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
should be avoided for the sake of sanity and readability.&lt;br /&gt;
&lt;br /&gt;
== Function-like macros ==&lt;br /&gt;
&lt;br /&gt;
Macros should have all-uppercase names.  If it is necessary to use&lt;br /&gt;
multiple statements, use braces, and wrap the whole thing in a&lt;br /&gt;
do-while(0) construct, such as&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#define FOOMACRO(x, y) do {                     \&lt;br /&gt;
    foo = (x) + (y);                            \&lt;br /&gt;
    f(y);                                       \&lt;br /&gt;
} while (0)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Leave off the semicolon at the end of a function-like macro, so that&lt;br /&gt;
it can be mostly used like a call to a function without a return&lt;br /&gt;
value.  Line up the backslashes to make it more readable.  Use M-x&lt;br /&gt;
c-backslash-region in emacs to do neat lined-up backslashes.&lt;br /&gt;
Parenthesize uses of arguments in the replacement text of a macro in&lt;br /&gt;
order to prevent weird interactions.&lt;br /&gt;
&lt;br /&gt;
== Namespaces ==&lt;br /&gt;
&lt;br /&gt;
The C standard reserves a bunch of namespaces for the implementation.&lt;br /&gt;
Don't stomp on them.  For practical purposes, any identifier with a&lt;br /&gt;
leading underscore should not be used.  (Technically, ^_[a-z].* are&lt;br /&gt;
reserved only for file scope, so should be safe for things smaller&lt;br /&gt;
than file scope, but it's better to be paranoid in this case.)&lt;br /&gt;
&lt;br /&gt;
POSIX reserves typedef names ending with _t as well.&lt;br /&gt;
&lt;br /&gt;
Recall that errno is a reserved identifier, and is permitted to be a&lt;br /&gt;
macro.  Therefore, do not use errno as the name of a structure member,&lt;br /&gt;
etc.&lt;br /&gt;
&lt;br /&gt;
Reserved namespaces are somewhat more restricted than this; read the&lt;br /&gt;
appropriate section of the C standard if you have questions.&lt;br /&gt;
&lt;br /&gt;
If you're writing new library code, pick a short prefix and stick with&lt;br /&gt;
it for any identifier with external linkage.  If for some reason a&lt;br /&gt;
library needs to have external symbols that should not be visible to&lt;br /&gt;
the application, pick another (related) prefix to use for the internal&lt;br /&gt;
globals.  This applies to typedef names, tag names, and preprocessor&lt;br /&gt;
identifiers as well.&lt;br /&gt;
&lt;br /&gt;
For the krb5 library, the prefix for public global symbols is &amp;quot;krb5_&amp;quot;.&lt;br /&gt;
Use &amp;quot;k5_&amp;quot; as a prefix for library internal globals.  Avoid using &amp;quot;__&amp;quot;&lt;br /&gt;
in symbol names, as it may confuse C++ implementations.  There are&lt;br /&gt;
admittedly a number of places where we leak thing into the namespace;&lt;br /&gt;
we should try to fix these.&lt;br /&gt;
&lt;br /&gt;
Header files should also not leak symbols.  Usually using the upcased&lt;br /&gt;
version of the prefix you've picked will suffice, e.g. &amp;quot;KRB5_&amp;quot; as a&lt;br /&gt;
CPP symbol prefix corresponding to &amp;quot;krb5_&amp;quot;.  In general, do not define&lt;br /&gt;
macros that are lowercase, in order to avoid confusion and to prevent&lt;br /&gt;
namespace collisions.&lt;br /&gt;
&lt;br /&gt;
Do not formulaically apply prefixes such as krb5_ or krb5int_ to static&lt;br /&gt;
function names.  It is better for static functions to have short&lt;br /&gt;
descriptive, and it can be confusing to see the krb5_ prefix on a symbol&lt;br /&gt;
which is not actually part of the krb5 API.&lt;br /&gt;
&lt;br /&gt;
The C standard only guarantees six case-insensitive characters to be&lt;br /&gt;
significant in external identifiers; this is largely regarded as&lt;br /&gt;
obsolescent even in 1989 and we will ignore it.  It does, however,&lt;br /&gt;
only guarantee 31 case-sensitive characters to be signficant in&lt;br /&gt;
internal identifiers, so do not use identifiers that differ beyond the&lt;br /&gt;
31st character.  This is unlikely to be a problem, though.&lt;br /&gt;
&lt;br /&gt;
== Function length ==&lt;br /&gt;
&lt;br /&gt;
Functions should not be longer than about 60 lines.  Strongly consider breaking up functions that are longer than this limit.&lt;br /&gt;
&lt;br /&gt;
=== Conformance ===&lt;br /&gt;
&lt;br /&gt;
Existing code conforms somewhat, with some egregious exceptions.  Some functions exceed 500 lines in length.  Older internal library symbols use &amp;quot;krb5int_&amp;quot; as a prefix instead of &amp;quot;k5_&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
=== Rationale ===&lt;br /&gt;
&lt;br /&gt;
Functions that are excessively lengthy are difficult to read.  Especially when the beginning of a control structure does not fit on the same screen or page as its end, maintenance can become problematic.  60 lines is about the maximum length that can comfortably fit on a sheet of letter-sized paper.&lt;br /&gt;
&lt;br /&gt;
== Nesting depth ==&lt;br /&gt;
&lt;br /&gt;
The maximum indentation level should not be more than four.  Deeply nested control flow generally indicates that a function needs to be broken into smaller pieces.&lt;br /&gt;
&lt;br /&gt;
=== Conformance ===&lt;br /&gt;
&lt;br /&gt;
Existing code conforms somewhat.&lt;br /&gt;
&lt;br /&gt;
=== Rationale ===&lt;br /&gt;
&lt;br /&gt;
Deeply nested control flow is difficult to read.&lt;br /&gt;
&lt;br /&gt;
== Copyright/License Statements ==&lt;br /&gt;
&lt;br /&gt;
Each applicable copyright/license statement for a file should appear by itself in a block comment.  Copyright/license statements should appear near the top of source files, after any emacs formatting or filename comments but before any descriptive comments or non-comment lines of source code.  See prototype/prototype.c and prototype/prototype.h for a more detailed example.&lt;br /&gt;
&lt;br /&gt;
All unique (except for year) copyright/license statements should appear in the top-level NOTICE file.&lt;br /&gt;
&lt;br /&gt;
=== Conformance ===&lt;br /&gt;
&lt;br /&gt;
Existing code mostly conforms, except that copyright/license statements do not usually appear by themselves in block comments.  In a few cases copyright/license statements appear later on in source files and should be moved to the top.&lt;br /&gt;
&lt;br /&gt;
=== Rationale ===&lt;br /&gt;
&lt;br /&gt;
Formatting license comments this way allows them to be extracted from source code by scripts, without the need for ugly markers.  The top-level NOTICE file makes it easier to satisfy the documentation requirements of licenses and to determine all of the terms under which MIT Kerberos may be used.&lt;br /&gt;
&lt;br /&gt;
== C99 features ==&lt;br /&gt;
&lt;br /&gt;
Use static inline functions instead of macros where possible.  Variadic macros may be used when needed.&lt;br /&gt;
&lt;br /&gt;
Where fixed-width integer types are required, use types from &amp;lt;stdint.h&amp;gt; such as int32_t.  Where an integer type of at least 64 bits is required, use &amp;quot;long long&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Do not use designated initializers or compound literals in code which is built on Windows.  They may be used in code which is not built on Windows.&lt;br /&gt;
&lt;br /&gt;
Avoid using declarations after statements (see [[#Local Variables | Local Variables]]).  Absolutely do not use them in code which is built on Windows.&lt;br /&gt;
&lt;br /&gt;
Do not use variable-length arrays or alloca().&lt;br /&gt;
&lt;br /&gt;
Do not use // comments (see [[Coding_style/Formatting#Comment Formatting | Comment Formatting]]).&lt;br /&gt;
&lt;br /&gt;
=== Conformance ===&lt;br /&gt;
&lt;br /&gt;
Older code uses Kerberos-specific fixed-width integer types such as krb5_int32.  Types from &amp;lt;stdint.h&amp;gt; can be used interchangeably with these types while we migrate away from them.&lt;br /&gt;
&lt;br /&gt;
=== Rationale ===&lt;br /&gt;
&lt;br /&gt;
At this time, official builds of Kerberos for Windows are performed using Visual Studio 2010, which supports only a subset of C99 features (see [[Portability research]]).  Support for the inline keyword is ensured by &amp;lt;win-mac.h&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Variable-length arrays are unsafe because there is no error checking.  If the length can be controlled by an attacker, security-critical bugs may result.&lt;br /&gt;
&lt;br /&gt;
== Misc. to be sorted ==&lt;br /&gt;
&lt;br /&gt;
Assume, for most purposes, working ANSI/ISO C ('89, not '99) support,&lt;br /&gt;
both for internal use and for applications compiling against Kerberos&lt;br /&gt;
header files and libraries.  Some exceptions are noted below.&lt;br /&gt;
&lt;br /&gt;
When calling a function through a variable which holds a function&lt;br /&gt;
pointer, explicitly deference the variable in order to make it easy&lt;br /&gt;
to see that the call is through a function pointer.  Do not explicitly&lt;br /&gt;
dereference the pointer if it is contained within a structure or union,&lt;br /&gt;
since there is no ambiguity in that case.  Do not explicitly take the&lt;br /&gt;
address of a function in order to assign it to a function pointer.&lt;br /&gt;
Thus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
int (*fp)(void);&lt;br /&gt;
int foofunc(void);&lt;br /&gt;
fp = foofunc;&lt;br /&gt;
x = (*fp)();&lt;br /&gt;
x = vtable.funcname();&lt;br /&gt;
x = vtable-&amp;gt;funcname();&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In general, do not take the address of an array.  It does not return a&lt;br /&gt;
pointer to the first element; it returns a pointer to the array&lt;br /&gt;
itself.  These are often identical when cast to an integral type, but&lt;br /&gt;
they are inherently of different types themselves.  Functions that&lt;br /&gt;
take array types or pointers to array types as arguments can be&lt;br /&gt;
particularly trouble-prone.&lt;br /&gt;
&lt;br /&gt;
If a function is declared to return a value, do not call &amp;quot;return&amp;quot;&lt;br /&gt;
without an argument or allow the flow of control to fall off the end&lt;br /&gt;
of the function.&lt;br /&gt;
&lt;br /&gt;
Always declare the return type of a function, even if it returns int.&lt;br /&gt;
Yes, this means declaring main() to return int, since main() is&lt;br /&gt;
required to return int by the standard.  If a function is not supposed&lt;br /&gt;
to return a value, declare it as returning void rather than omitting&lt;br /&gt;
the return type, which will default the return type to int.&lt;br /&gt;
&lt;br /&gt;
Use ANSI C prototype-style function declarations and definitions.  For functions with no parameters, use &amp;quot;(void)&amp;quot; in both the declaration and definition.&lt;br /&gt;
&lt;br /&gt;
Don't pass or return structures in API functions except by address.&lt;br /&gt;
&lt;br /&gt;
Every function should have a block comment describing briefly in complete sentences what it does, what inputs and outputs it has, and what error codes it can return.  It should also describe any unusual aspects of the function.  If the function is prototyped in a header file, the block comment should precede the prototype in the header file; otherwise it should precede the function definition.&lt;br /&gt;
&lt;br /&gt;
Strive to make your code capable of compiling using &amp;quot;gcc -Wall&lt;br /&gt;
-Wmissing-prototypes -Wtraditional -Wcast-align&lt;br /&gt;
-pedantic&amp;quot; [XXX need to rethink this&lt;br /&gt;
somewhat] without generating any errors or warnings.  Do not, however,&lt;br /&gt;
compile using the &amp;quot;-ansi&amp;quot; flag to gcc, since that can result in odd&lt;br /&gt;
behavior with header files on some systems, causing some necessary&lt;br /&gt;
symbols to not be defined.&lt;/div&gt;</summary>
		<author><name>Ghudson</name></author>	</entry>

	<entry>
		<id>https://k5wiki.kerberos.org/wiki?title=Coding_style/Practices&amp;diff=6041</id>
		<title>Coding style/Practices</title>
		<link rel="alternate" type="text/html" href="https://k5wiki.kerberos.org/wiki?title=Coding_style/Practices&amp;diff=6041"/>
				<updated>2024-09-22T19:20:46Z</updated>
		
		<summary type="html">&lt;p&gt;Ghudson: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__&lt;br /&gt;
==Quick Summary==&lt;br /&gt;
&lt;br /&gt;
* Avoid strcpy, strcat, sprintf, and *scanf.&lt;br /&gt;
* Use &amp;quot;goto cleanup&amp;quot; to ensure that resources are released on all function exit paths.&lt;br /&gt;
* Keep track of which pointers are owners and which are aliases; initialize owner pointers to NULL.&lt;br /&gt;
* Avoid creating structure instances containing a mix of owner and alias pointers.&lt;br /&gt;
* Check untrusted integer values before operating on them to avoid overflows.&lt;br /&gt;
* Use size_t for array indexes when the array is unbounded.  Use the same type as the bound when it is.&lt;br /&gt;
* Name output variables ending with &amp;quot;_out&amp;quot;.  Initialize them at the beginning of a function, then don't touch them until just before successful return.&lt;br /&gt;
* Don't use assignments as truth values except (perhaps) in a while loop.&lt;br /&gt;
* Use NULL for the null pointer and '\0' for the null character.  Don't use pointers or characters as truth values.&lt;br /&gt;
* Put braces around flow control statement bodies if they are more than one line long, and around any do-while loop.&lt;br /&gt;
* Try to keep preprocessor statements outside of function bodies.&lt;br /&gt;
* Avoid declarations of local variables in inner scope.&lt;br /&gt;
* Parenthesize (sparingly) to avoid C precedence confusion, especially when using bitwise operators.&lt;br /&gt;
* Use all-uppercase names for macros.&lt;br /&gt;
* Avoid stepping on reserved C namespaces.&lt;br /&gt;
* Use the krb5_ prefix for libkrb5 API functions, and the k5_ prefix for linker-visible internal functions.  Don't use a prefix for static functions.&lt;br /&gt;
* Don't use designated initializers or compound literals in code which is built on Windows.&lt;br /&gt;
* Don't use variable-length arrays or alloca().&lt;br /&gt;
* Avoid long or deeply nested function bodies.  Use helpers to limit function complexity.&lt;br /&gt;
* Function calls through pointers should look like &amp;quot;(*fp)(args)&amp;quot; or &amp;quot;vtable-&amp;gt;method(vars)&amp;quot;.&lt;br /&gt;
* Always declare function return types.  Use ANSI C-style function definitions.&lt;br /&gt;
* Don't pass or return structures by value in API functions.&lt;br /&gt;
* Precede functions with block comments describing what they do.&lt;br /&gt;
* Make your code warning-clean under the gcc warning flags used in our build system.&lt;br /&gt;
&lt;br /&gt;
== String Handling ==&lt;br /&gt;
&lt;br /&gt;
Code should not use any of the following functions: strcpy, strcat, sprintf, or any *scanf function.&lt;br /&gt;
&lt;br /&gt;
Dynamically allocated buffers are preferred to fixed-sized buffers.  When using dynamic buffers:&lt;br /&gt;
* Use strdup or asprintf for simple constructions.&lt;br /&gt;
* Use the k5buf module (k5-buf.h) for complex constructions.  If this is not desirable, strlcpy and strlcat are valid alternatives.&lt;br /&gt;
&lt;br /&gt;
Substitute versions of strlcpy, strlcat, and asprintf, for operating systems that don't supply them, are declared in k5-platform.h and defined in the support library (which practically everything in the tree links directly against).&lt;br /&gt;
&lt;br /&gt;
When using fixed-sized buffers:&lt;br /&gt;
* Use strlcpy for simple copies.&lt;br /&gt;
* Use snprintf for simple compound constructions.  Avoid using precision or field width specifiers in snprintf format strings.&lt;br /&gt;
* To check for truncation when using snprintf, use the following approach:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
result = snprintf(buffer, sizeof(buffer), &amp;quot;format string&amp;quot;, ...);&lt;br /&gt;
if (SNPRINTF_OVERFLOW(result, sizeof(buffer))&lt;br /&gt;
    handle_overflow_error;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The SNPRINTF_OVERFLOW macro is defined in k5-platform.h.&lt;br /&gt;
&lt;br /&gt;
=== Current conformance ===&lt;br /&gt;
&lt;br /&gt;
Existing code mostly conforms, with some exceptions.&lt;br /&gt;
&lt;br /&gt;
=== Rationale ===&lt;br /&gt;
&lt;br /&gt;
It is relatively common to audit a code base such as krb5 and flag all uses of strcpy and similar functions, even if they are used safely.  Verifying that the function is used safely requires manual inspection.  Using safer alternatives does not guarantee code safety, but does reduce the likelihood of a catastrophic buffer overflow vulnerability.&lt;br /&gt;
&lt;br /&gt;
In some compilation environments under Solaris, field widths and precisions are computed using screen columns rather than bytes.&lt;br /&gt;
&lt;br /&gt;
sprintf returns a signed integer; buffer sizes are typically size_t (which is an unsigned type).  Comparing the two directly will result in a warning from some compilers, and has unpredictable semantics depending on the relative widths of int and size_t.  Also, some sprintf implementations, such as the one in Solaris prior to version 10, return -1 on a buffer overflow, whereas the C99 behavior returns the number of bytes which would have been written to the string.  The SNPRINTF_OVERFLOW macro uses casts to address both issues.&lt;br /&gt;
&lt;br /&gt;
The k5buf module safely allows multi-step string construction within fixed-size or dynamic buffers without performing an error check on each append, and without pre-computing lengths.  Errors need only be checked when the resulting string needs to be read or handed off to another function.&lt;br /&gt;
&lt;br /&gt;
== Exception Handling ==&lt;br /&gt;
&lt;br /&gt;
If a function allocates several resources and has many exit paths, use the following general structure when possible:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
    krb5_error_code ret;&lt;br /&gt;
    char *ptr1 = NULL;&lt;br /&gt;
    krb5_blah *ptr2 = NULL;&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
    ret = another_function(...);&lt;br /&gt;
    if (ret)&lt;br /&gt;
        goto cleanup;&lt;br /&gt;
...&lt;br /&gt;
cleanup:&lt;br /&gt;
    free(ptr1);&lt;br /&gt;
    krb5_free_blah(ptr2);&lt;br /&gt;
    return ret;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(free() and krb5_free_foo() functions will both accept NULL as input and do nothing.)  Simpler functions may use simpler control structures, but do not get to the point of freeing the same resource in several different places within a function depending on the exit path.  Do not use multiple exit labels.&lt;br /&gt;
&lt;br /&gt;
Unless constrained by an API standard such as GSSAPI, functions which can fail should return a krb5_error_code.  Error codes are defined in com_err tables, usually located in src/lib/krb5/error_tables.&lt;br /&gt;
&lt;br /&gt;
Functions can also set extended error messages using krb5_set_error_message() (or, in dependencies of libkrb5, krb5int_set_error() on &amp;amp;context-&amp;gt;err).  Code should set extended error messages when an error condition is moderately likely to occur and the default string for the error code is insufficiently clear.  Avoid exposing function names and other implementation details in error messages.&lt;br /&gt;
&lt;br /&gt;
After ignoring or handling an error code, krb5_clear_error_message() (or krb5int_clear_error()) should be used to ensure that an extended error message is not applied erroneously to a later instance of the same error code.  This can be especially important in loops.&lt;br /&gt;
&lt;br /&gt;
=== Current conformance ===&lt;br /&gt;
&lt;br /&gt;
Existing code mostly conforms, with some exceptions.&lt;br /&gt;
&lt;br /&gt;
=== Rationale ===&lt;br /&gt;
&lt;br /&gt;
The &amp;quot;goto cleanup&amp;quot; flow control is the most reliable way to avoid resource leaks within the constraints of the krb5 code base.  Within libraries, the code base does not abort on memory allocation failure, so tends to have many exit paths within some functions.&lt;br /&gt;
&lt;br /&gt;
Extended error messages can provide invaluable information about error conditions, but merely serve to expand code if used mechanically.&lt;br /&gt;
&lt;br /&gt;
== Memory management ==&lt;br /&gt;
&lt;br /&gt;
An allocated object can have multiple pointers to it.  The pointer through which the object will eventually be freed is called the owner, and other pointers to the object are called aliases.  The owner may change over the lifetime of the object.&lt;br /&gt;
&lt;br /&gt;
When transferring ownership of a pointer (such as when returning an allocated value to a caller via an output parameter), null out the old owner pointer unless it is about to be destroyed or go out of scope.&lt;br /&gt;
&lt;br /&gt;
Avoid mixing owner pointers and aliases within a structure.  Create additional local variables to act as owner pointers when this situation occurs.&lt;br /&gt;
&lt;br /&gt;
Initialize variables containing owner pointers to NULL.  Free the pointed-to objects (unconditionally, when possible) in the function's cleanup handler.&lt;br /&gt;
&lt;br /&gt;
In some cases these rules may not be reasonable; for instance, temporary memory allocated within a loop body must be freed within the loop body, not in the cleanup handler.  Break these rules when necessary, but also make liberal use of helper functions to simplify memory management.&lt;br /&gt;
&lt;br /&gt;
=== Current conformance ===&lt;br /&gt;
&lt;br /&gt;
Newer code mostly conforms; older code does not.&lt;br /&gt;
&lt;br /&gt;
=== Rationale ===&lt;br /&gt;
&lt;br /&gt;
Following these rules makes it easier to verify that a function contains no memory leaks, no double frees, and no dereferences after frees.  These rules also keep memory management logic out of the core logic of a function, making it easier to understand.&lt;br /&gt;
&lt;br /&gt;
== Avoiding integer overflows ==&lt;br /&gt;
&lt;br /&gt;
When operating on integer values derived from untrusted input, care must be taken to prevent overflows.  When possible, compare suspect values without operating on them, not the results of operating on them:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/* This is safe. */&lt;br /&gt;
if (offset &amp;gt; len - current)&lt;br /&gt;
   return EINVAL;&lt;br /&gt;
/* This is dangerous if offset is unbounded. */&lt;br /&gt;
if (current + offset &amp;gt; len)&lt;br /&gt;
    return EINVAL;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When indexing an array with no specified integer bound (such as a null-terminated array), use size_t for the index type.  When the array does have an integer bound, use the same type as the array bound.&lt;br /&gt;
&lt;br /&gt;
== Output parameter handling ==&lt;br /&gt;
&lt;br /&gt;
Output parameter names should typically end in &amp;quot;_out&amp;quot;.  Output parameters should typically be the last parameters to a function, with certain exceptions (such as context-like parameters).&lt;br /&gt;
&lt;br /&gt;
Avoid filling in a caller-allocated structure.  Instead, allocate the structure within the function and output a pointer to the structure.&lt;br /&gt;
&lt;br /&gt;
If a function has output parameters, their values should be defined in all cases, including on failure.  Most of the time, this means setting output parameters to NULL or zero at the beginning of the function, and not assigning real values to the output parameters until successful completion from the function is guaranteed.  A typical function with output parameters should look something like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
krb5_error_code&lt;br /&gt;
function_with_output_param(type *input_param, type *ptr_out)&lt;br /&gt;
{&lt;br /&gt;
  krb5_error_code ret;&lt;br /&gt;
  type *ptr = NULL;&lt;br /&gt;
&lt;br /&gt;
  *ptr_out = NULL;&lt;br /&gt;
&lt;br /&gt;
  stuff that can go wrong here, allocating ptr;&lt;br /&gt;
&lt;br /&gt;
  *ptr_out = ptr;&lt;br /&gt;
  ptr = NULL;&lt;br /&gt;
&lt;br /&gt;
cleanup:&lt;br /&gt;
  free_function(ptr);&lt;br /&gt;
  other cleanup code here;&lt;br /&gt;
  return ret;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Simple wrapper functions can delegate the initialization of output paremeters to the functions they wrap, ''unless'' they are invoking the wrapped function through a function pointer.&lt;br /&gt;
&lt;br /&gt;
=== Current conformance ===&lt;br /&gt;
&lt;br /&gt;
Existing code mostly does not conform.  Filling in caller-allocated structures is common (though far from universal) in the public libkrb5 API.&lt;br /&gt;
&lt;br /&gt;
=== Rationale ===&lt;br /&gt;
&lt;br /&gt;
Naming output parameters with an &amp;quot;_out&amp;quot; suffix helps readers easily identify them, and also makes it clearer when a resource's ownership is transferred to the caller.  Since output parameters are only used near the beginning and end of a function, the extra verbosity is not very burdensome.&lt;br /&gt;
&lt;br /&gt;
Initializing output parameters makes it clear to static analysis tools that the previous value of the output parameter will not be used.  If there happens to be a bug in the function such that it returns success but does not set output parameters, or in the caller such that it uses an output parameter even though the function returned failure, then the bug will result in predictable behavior (generally a NULL pointer dereference) with no security consequences beyond a denial of service attack.&lt;br /&gt;
&lt;br /&gt;
== Assignments as truth values ==&lt;br /&gt;
&lt;br /&gt;
Do not use assignments as truth values.  Rather than this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/* bad style */&lt;br /&gt;
if ((ret = krb5_foo()))&lt;br /&gt;
    /* ... */;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
do this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/* better style */&lt;br /&gt;
ret = krb5_foo();&lt;br /&gt;
if (ret)&lt;br /&gt;
    /* ... */;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Current conformance ===&lt;br /&gt;
&lt;br /&gt;
Existing code varies widely.&lt;br /&gt;
&lt;br /&gt;
=== Rationale ===&lt;br /&gt;
&lt;br /&gt;
This makes the code easier to read, and also makes it easier to use&lt;br /&gt;
debuggers.  It may be excusable to put assignments into the&lt;br /&gt;
conditional espression of a &amp;quot;while&amp;quot; statement, though, like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
while ((ch = getopt(argc, argv, &amp;quot;abn&amp;quot;)) != -1)&lt;br /&gt;
    /* ... */;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Using assignments as truth values in conditional expressions (&amp;quot;ternary expressions&amp;quot;) may make&lt;br /&gt;
code particularly impenetrable.&lt;br /&gt;
&lt;br /&gt;
== The many names of zero ==&lt;br /&gt;
&lt;br /&gt;
There are at least three types of &amp;quot;zero&amp;quot; known to C.  These are the&lt;br /&gt;
integer zero (0), the null pointer constant (NULL), and the character&lt;br /&gt;
constant zero ('\0').  Yes, these are usually all technically the&lt;br /&gt;
integer zero.  Use them in their correct contexts.  (Purists will&lt;br /&gt;
point out that 0 is a valid null pointer constant; still, do not use 0&lt;br /&gt;
to specify a null pointer constant.  For further unconfusion, read the&lt;br /&gt;
section on null pointer constants in the comp.lang.c FAQ.)  Do not use a lone&lt;br /&gt;
variable as a truth value unless it's of integer type.  Thus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
int i;&lt;br /&gt;
char *cp;&lt;br /&gt;
/* ... */&lt;br /&gt;
if (i)&lt;br /&gt;
    /* ... */;&lt;br /&gt;
if (cp != NULL) {&lt;br /&gt;
    while (*cp != '\0')&lt;br /&gt;
        /* ... */;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Do not cast uses of NULL unless you're calling a function with a&lt;br /&gt;
variable number of arguments, in which case you should cast it to to&lt;br /&gt;
the appropriate pointer type.  (NULL may be defined as 0, and an integer 0&lt;br /&gt;
may not be the same size in the argument list as a pointer on a 64-bit&lt;br /&gt;
platform.)  Likewise, do not cast the return value&lt;br /&gt;
from malloc() and friends; the prototype should declare them properly&lt;br /&gt;
as returning a void&amp;amp;nbsp;* and thus shouldn't require an explicit cast.&lt;br /&gt;
&lt;br /&gt;
In any case, reading the section in the C FAQ on null pointers is&lt;br /&gt;
highly recommended to remove confusion regarding null pointers in C,&lt;br /&gt;
since this is a subject of much confusion to even experienced&lt;br /&gt;
programmers.  In particular, if you do not understand why using&lt;br /&gt;
calloc() to allocate a struct that contains pointer members or why&lt;br /&gt;
calling memset() to initialize such a struct to all-bytes-zero is&lt;br /&gt;
wrong, reread that section again.  Due to the prevalence of this practice and the practical difficulties of eliminating it, our [[portability assumptions]] currently require that platforms represent null pointers as all-bits-zero.&lt;br /&gt;
&lt;br /&gt;
== Brace placement ==&lt;br /&gt;
&lt;br /&gt;
Control flow statements that have a single statement as their body&lt;br /&gt;
should nevertheless have braces around their bodies if the body is&lt;br /&gt;
more than one line long, especially in the case of stacked multiple&lt;br /&gt;
if-else clauses; use:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
if (x) {&lt;br /&gt;
    if (y)&lt;br /&gt;
        foo();&lt;br /&gt;
    else&lt;br /&gt;
        bar();&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
instead of:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/* bad style */&lt;br /&gt;
if (x)&lt;br /&gt;
    if (y)&lt;br /&gt;
        foo();&lt;br /&gt;
    else&lt;br /&gt;
        bar();&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
which, while legible to the compiler, may confuse human readers and&lt;br /&gt;
make the code less maintainable, especially if new branches get added&lt;br /&gt;
to any of the clauses.&lt;br /&gt;
&lt;br /&gt;
If you are writing a do-while loop that has only one statement in its&lt;br /&gt;
body, put braces around it anyway, since the while clause may be&lt;br /&gt;
mistaken for a while loop with an empty body.  Don't do this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/* bad style */&lt;br /&gt;
do&lt;br /&gt;
    foo();&lt;br /&gt;
while (x);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Instead, write this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/* better style */&lt;br /&gt;
do {&lt;br /&gt;
    foo();&lt;br /&gt;
} while (x);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Preprocessor conditionals ==&lt;br /&gt;
&lt;br /&gt;
Instead of scattering &amp;lt;code&amp;gt;#ifdef&amp;lt;/code&amp;gt; or other preprocessor conditionals throughout the code use preprocessor conditionals to control the definition of a function-like macro, or similar construct, which is used instead of embedded preprocessor conditionals in code.&lt;br /&gt;
&lt;br /&gt;
Instead of this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    do_something();&lt;br /&gt;
    /* bad style */&lt;br /&gt;
#ifdef DEBUG&lt;br /&gt;
    fprintf(stderr, &amp;quot;did something\n&amp;quot;);&lt;br /&gt;
#endif&lt;br /&gt;
    do_something_else();&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
do something more like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#ifdef DEBUG&lt;br /&gt;
#define DPRINTF(x) fprintf(stderr, x)&lt;br /&gt;
#else&lt;br /&gt;
#define DPRINTF(x)		/* empty */&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
/* ... */&lt;br /&gt;
&lt;br /&gt;
    do_something();&lt;br /&gt;
    /* better style */&lt;br /&gt;
    DPRINTF((&amp;quot;did something\n&amp;quot;));&lt;br /&gt;
    do_something_else();&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Do not intersperse conditional compilation&lt;br /&gt;
directives with control flow statements, as some combination of&lt;br /&gt;
&amp;lt;code&amp;gt;#define&amp;lt;/code&amp;gt;d symbols may result in statements getting eaten by dangling&lt;br /&gt;
bits of control flow statements.  When it is not possible to avoid&lt;br /&gt;
this questionable practice (you really should rewrite the relevant&lt;br /&gt;
code section), make use of redundant braces to make a compiler&lt;br /&gt;
error more likely than incorrect runtime behavior (such as&lt;br /&gt;
inadvertently providing someone with a root shell -- this has actually happened, long ago).&lt;br /&gt;
&lt;br /&gt;
Do not intersperse conditional compilation directives with control&lt;br /&gt;
flow statements in such a way that confuses emacs cc-mode.  Not only&lt;br /&gt;
does emacs get confused, but the code becomes more difficult to read&lt;br /&gt;
and maintain.  Therefore, avoid code like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    /* bad style */&lt;br /&gt;
    if (x) {&lt;br /&gt;
        f();&lt;br /&gt;
    }&lt;br /&gt;
#ifdef FOO&lt;br /&gt;
    else if (y) {&lt;br /&gt;
#else&lt;br /&gt;
    else {&lt;br /&gt;
#endif&lt;br /&gt;
        g();&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Put comments after conditional compilation directives such as &amp;quot;#else&amp;quot;&lt;br /&gt;
and &amp;quot;#endif&amp;quot;.  Make them correspond to the sense of the value that&lt;br /&gt;
controls the compilation of the section they are closing, i.e.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#ifdef FOO&lt;br /&gt;
/* ... */&lt;br /&gt;
#else /* !FOO */&lt;br /&gt;
/* ... */&lt;br /&gt;
#endif /* !FOO */&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Also, in the case of more complex conditional compilation directives,&lt;br /&gt;
write the comments like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#if defined(FOO) || defined(BAR)&lt;br /&gt;
/* ... */&lt;br /&gt;
#else /* !(defined(FOO) || defined(BAR)) */&lt;br /&gt;
/* ... */&lt;br /&gt;
#endif /* !(defined(FOO) || defined(BAR)) */&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Conformance ===&lt;br /&gt;
&lt;br /&gt;
Existing code mostly does not conform.&lt;br /&gt;
&lt;br /&gt;
=== Rationale ===&lt;br /&gt;
&lt;br /&gt;
Instances of &amp;quot;ifdef soup&amp;quot; make code more difficult to read, and make it more difficult to recognize bugs.  It also interferes with automated reformatting and analysis tools.&lt;br /&gt;
&lt;br /&gt;
== Local variables ==&lt;br /&gt;
&lt;br /&gt;
Do not declare variables in an inner scope, e.g. inside the compound&lt;br /&gt;
substatement of an if statement, unless the complexity of the code&lt;br /&gt;
really demands that the variables be declared that way.  In such&lt;br /&gt;
situations, the function could probably stand to be broken up into&lt;br /&gt;
smaller chunks anyway.  Do not declare variables in an inner scope&lt;br /&gt;
that shadow ones in an outer scope, since this leads to confusion.&lt;br /&gt;
Also, some debugging environments, such as gdb under Solaris, can't&lt;br /&gt;
see variables declared in an inner scope, so declaring such variables&lt;br /&gt;
will make maintenance more difficult as well.&lt;br /&gt;
&lt;br /&gt;
== Placement of parentheses ==&lt;br /&gt;
&lt;br /&gt;
Parenthesize expressions that may be confusing, particularly where C's&lt;br /&gt;
precedences are broken.  For example, the shift operators have lower&lt;br /&gt;
precedence than the +, -, *, /, and % operators.  Perhaps the most&lt;br /&gt;
familiar C precedence quirk is that equality and relational operators&lt;br /&gt;
are of higher precedence than assignment operators.  Less well known&lt;br /&gt;
is that the bitwise operators are of a lower precedence than equality&lt;br /&gt;
and relational operators.&lt;br /&gt;
&lt;br /&gt;
The sizeof operator takes either a unary expression or a parenthesized&lt;br /&gt;
type name.  It is not necessary to parenthesize the operand of sizeof&lt;br /&gt;
if it is applied to a unary expression, but still, always parenthesize&lt;br /&gt;
the operand of the sizeof operator.  The sizeof operator does not&lt;br /&gt;
evaluate its operand if it is a unary expression, so usages such as&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
s = sizeof(++foo);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
should be avoided for the sake of sanity and readability.&lt;br /&gt;
&lt;br /&gt;
== Function-like macros ==&lt;br /&gt;
&lt;br /&gt;
Macros should have all-uppercase names.  If it is necessary to use&lt;br /&gt;
multiple statements, use braces, and wrap the whole thing in a&lt;br /&gt;
do-while(0) construct, such as&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#define FOOMACRO(x, y) do {                     \&lt;br /&gt;
    foo = (x) + (y);                            \&lt;br /&gt;
    f(y);                                       \&lt;br /&gt;
} while (0)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Leave off the semicolon at the end of a function-like macro, so that&lt;br /&gt;
it can be mostly used like a call to a function without a return&lt;br /&gt;
value.  Line up the backslashes to make it more readable.  Use M-x&lt;br /&gt;
c-backslash-region in emacs to do neat lined-up backslashes.&lt;br /&gt;
Parenthesize uses of arguments in the replacement text of a macro in&lt;br /&gt;
order to prevent weird interactions.&lt;br /&gt;
&lt;br /&gt;
== Namespaces ==&lt;br /&gt;
&lt;br /&gt;
The C standard reserves a bunch of namespaces for the implementation.&lt;br /&gt;
Don't stomp on them.  For practical purposes, any identifier with a&lt;br /&gt;
leading underscore should not be used.  (Technically, ^_[a-z].* are&lt;br /&gt;
reserved only for file scope, so should be safe for things smaller&lt;br /&gt;
than file scope, but it's better to be paranoid in this case.)&lt;br /&gt;
&lt;br /&gt;
POSIX reserves typedef names ending with _t as well.&lt;br /&gt;
&lt;br /&gt;
Recall that errno is a reserved identifier, and is permitted to be a&lt;br /&gt;
macro.  Therefore, do not use errno as the name of a structure member,&lt;br /&gt;
etc.&lt;br /&gt;
&lt;br /&gt;
Reserved namespaces are somewhat more restricted than this; read the&lt;br /&gt;
appropriate section of the C standard if you have questions.&lt;br /&gt;
&lt;br /&gt;
If you're writing new library code, pick a short prefix and stick with&lt;br /&gt;
it for any identifier with external linkage.  If for some reason a&lt;br /&gt;
library needs to have external symbols that should not be visible to&lt;br /&gt;
the application, pick another (related) prefix to use for the internal&lt;br /&gt;
globals.  This applies to typedef names, tag names, and preprocessor&lt;br /&gt;
identifiers as well.&lt;br /&gt;
&lt;br /&gt;
For the krb5 library, the prefix for public global symbols is &amp;quot;krb5_&amp;quot;.&lt;br /&gt;
Use &amp;quot;k5_&amp;quot; as a prefix for library internal globals.  Avoid using &amp;quot;__&amp;quot;&lt;br /&gt;
in symbol names, as it may confuse C++ implementations.  There are&lt;br /&gt;
admittedly a number of places where we leak thing into the namespace;&lt;br /&gt;
we should try to fix these.&lt;br /&gt;
&lt;br /&gt;
Header files should also not leak symbols.  Usually using the upcased&lt;br /&gt;
version of the prefix you've picked will suffice, e.g. &amp;quot;KRB5_&amp;quot; as a&lt;br /&gt;
CPP symbol prefix corresponding to &amp;quot;krb5_&amp;quot;.  In general, do not define&lt;br /&gt;
macros that are lowercase, in order to avoid confusion and to prevent&lt;br /&gt;
namespace collisions.&lt;br /&gt;
&lt;br /&gt;
Do not formulaically apply prefixes such as krb5_ or krb5int_ to static&lt;br /&gt;
function names.  It is better for static functions to have short&lt;br /&gt;
descriptive, and it can be confusing to see the krb5_ prefix on a symbol&lt;br /&gt;
which is not actually part of the krb5 API.&lt;br /&gt;
&lt;br /&gt;
The C standard only guarantees six case-insensitive characters to be&lt;br /&gt;
significant in external identifiers; this is largely regarded as&lt;br /&gt;
obsolescent even in 1989 and we will ignore it.  It does, however,&lt;br /&gt;
only guarantee 31 case-sensitive characters to be signficant in&lt;br /&gt;
internal identifiers, so do not use identifiers that differ beyond the&lt;br /&gt;
31st character.  This is unlikely to be a problem, though.&lt;br /&gt;
&lt;br /&gt;
== Function length ==&lt;br /&gt;
&lt;br /&gt;
Functions should not be longer than about 60 lines.  Strongly consider breaking up functions that are longer than this limit.&lt;br /&gt;
&lt;br /&gt;
=== Conformance ===&lt;br /&gt;
&lt;br /&gt;
Existing code conforms somewhat, with some egregious exceptions.  Some functions exceed 500 lines in length.  Older internal library symbols use &amp;quot;krb5int_&amp;quot; as a prefix instead of &amp;quot;k5_&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
=== Rationale ===&lt;br /&gt;
&lt;br /&gt;
Functions that are excessively lengthy are difficult to read.  Especially when the beginning of a control structure does not fit on the same screen or page as its end, maintenance can become problematic.  60 lines is about the maximum length that can comfortably fit on a sheet of letter-sized paper.&lt;br /&gt;
&lt;br /&gt;
== Nesting depth ==&lt;br /&gt;
&lt;br /&gt;
The maximum indentation level should not be more than four.  Deeply nested control flow generally indicates that a function needs to be broken into smaller pieces.&lt;br /&gt;
&lt;br /&gt;
=== Conformance ===&lt;br /&gt;
&lt;br /&gt;
Existing code conforms somewhat.&lt;br /&gt;
&lt;br /&gt;
=== Rationale ===&lt;br /&gt;
&lt;br /&gt;
Deeply nested control flow is difficult to read.&lt;br /&gt;
&lt;br /&gt;
== Copyright/License Statements ==&lt;br /&gt;
&lt;br /&gt;
Each applicable copyright/license statement for a file should appear by itself in a block comment.  Copyright/license statements should appear near the top of source files, after any emacs formatting or filename comments but before any descriptive comments or non-comment lines of source code.  See prototype/prototype.c and prototype/prototype.h for a more detailed example.&lt;br /&gt;
&lt;br /&gt;
All unique (except for year) copyright/license statements should appear in the top-level NOTICE file.&lt;br /&gt;
&lt;br /&gt;
=== Conformance ===&lt;br /&gt;
&lt;br /&gt;
Existing code mostly conforms, except that copyright/license statements do not usually appear by themselves in block comments.  In a few cases copyright/license statements appear later on in source files and should be moved to the top.&lt;br /&gt;
&lt;br /&gt;
=== Rationale ===&lt;br /&gt;
&lt;br /&gt;
Formatting license comments this way allows them to be extracted from source code by scripts, without the need for ugly markers.  The top-level NOTICE file makes it easier to satisfy the documentation requirements of licenses and to determine all of the terms under which MIT Kerberos may be used.&lt;br /&gt;
&lt;br /&gt;
== C99 features ==&lt;br /&gt;
&lt;br /&gt;
Use static inline functions instead of macros where possible.  Variadic macros may be used when needed.&lt;br /&gt;
&lt;br /&gt;
Where fixed-width integer types are required, use types from &amp;lt;stdint.h&amp;gt; such as int32_t.  Where an integer type of at least 64 bits is required, use &amp;quot;long long&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Do not use designated initializers or compound literals in code which is built on Windows.  They may be used in code which is not built on Windows.&lt;br /&gt;
&lt;br /&gt;
Avoid using declarations after statements (see [[#Local Variables | Local Variables]]).  Absolutely do not use them in code which is built on Windows.&lt;br /&gt;
&lt;br /&gt;
Do not use variable-length arrays or alloca().&lt;br /&gt;
&lt;br /&gt;
Do not use // comments (see [[Coding_style/Formatting#Comment Formatting | Comment Formatting]]).&lt;br /&gt;
&lt;br /&gt;
=== Conformance ===&lt;br /&gt;
&lt;br /&gt;
Older code uses Kerberos-specific fixed-width integer types such as krb5_int32.  Types from &amp;lt;stdint.h&amp;gt; can be used interchangeably with these types while we migrate away from them.&lt;br /&gt;
&lt;br /&gt;
=== Rationale ===&lt;br /&gt;
&lt;br /&gt;
At this time, official builds of Kerberos for Windows are performed using Visual Studio 2010, which supports only a subset of C99 features (see [[Portability research]]).  Support for the inline keyword is ensured by &amp;lt;win-mac.h&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Variable-length arrays are unsafe because there is no error checking.  If the length can be controlled by an attacker, security-critical bugs may result.&lt;br /&gt;
&lt;br /&gt;
== Misc. to be sorted ==&lt;br /&gt;
&lt;br /&gt;
Assume, for most purposes, working ANSI/ISO C ('89, not '99) support,&lt;br /&gt;
both for internal use and for applications compiling against Kerberos&lt;br /&gt;
header files and libraries.  Some exceptions are noted below.&lt;br /&gt;
&lt;br /&gt;
When calling a function through a variable which holds a function&lt;br /&gt;
pointer, explicitly deference the variable in order to make it easy&lt;br /&gt;
to see that the call is through a function pointer.  Do not explicitly&lt;br /&gt;
dereference the pointer if it is contained within a structure or union,&lt;br /&gt;
since there is no ambiguity in that case.  Do not explicitly take the&lt;br /&gt;
address of a function in order to assign it to a function pointer.&lt;br /&gt;
Thus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
int (*fp)(void);&lt;br /&gt;
int foofunc(void);&lt;br /&gt;
fp = foofunc;&lt;br /&gt;
x = (*fp)();&lt;br /&gt;
x = vtable.funcname();&lt;br /&gt;
x = vtable-&amp;gt;funcname();&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In general, do not take the address of an array.  It does not return a&lt;br /&gt;
pointer to the first element; it returns a pointer to the array&lt;br /&gt;
itself.  These are often identical when cast to an integral type, but&lt;br /&gt;
they are inherently of different types themselves.  Functions that&lt;br /&gt;
take array types or pointers to array types as arguments can be&lt;br /&gt;
particularly trouble-prone.&lt;br /&gt;
&lt;br /&gt;
If a function is declared to return a value, do not call &amp;quot;return&amp;quot;&lt;br /&gt;
without an argument or allow the flow of control to fall off the end&lt;br /&gt;
of the function.&lt;br /&gt;
&lt;br /&gt;
Always declare the return type of a function, even if it returns int.&lt;br /&gt;
Yes, this means declaring main() to return int, since main() is&lt;br /&gt;
required to return int by the standard.  If a function is not supposed&lt;br /&gt;
to return a value, declare it as returning void rather than omitting&lt;br /&gt;
the return type, which will default the return type to int.&lt;br /&gt;
&lt;br /&gt;
Use ANSI C prototype-style function declarations and definitions.  For functions with no parameters, use &amp;quot;(void)&amp;quot; in both the declaration and definition.&lt;br /&gt;
&lt;br /&gt;
Don't pass or return structures in API functions except by address.&lt;br /&gt;
&lt;br /&gt;
Every function should have a block comment describing briefly in complete sentences what it does, what inputs and outputs it has, and what error codes it can return.  It should also describe any unusual aspects of the function.  If the function is prototyped in a header file, the block comment should precede the prototype in the header file; otherwise it should precede the function definition.&lt;br /&gt;
&lt;br /&gt;
Strive to make your code capable of compiling using &amp;quot;gcc -Wall&lt;br /&gt;
-Wmissing-prototypes -Wtraditional -Wcast-align&lt;br /&gt;
-pedantic&amp;quot; [XXX need to rethink this&lt;br /&gt;
somewhat] without generating any errors or warnings.  Do not, however,&lt;br /&gt;
compile using the &amp;quot;-ansi&amp;quot; flag to gcc, since that can result in odd&lt;br /&gt;
behavior with header files on some systems, causing some necessary&lt;br /&gt;
symbols to not be defined.&lt;/div&gt;</summary>
		<author><name>Ghudson</name></author>	</entry>

	<entry>
		<id>https://k5wiki.kerberos.org/wiki?title=Cleanups&amp;diff=6040</id>
		<title>Cleanups</title>
		<link rel="alternate" type="text/html" href="https://k5wiki.kerberos.org/wiki?title=Cleanups&amp;diff=6040"/>
				<updated>2023-07-29T06:40:09Z</updated>
		
		<summary type="html">&lt;p&gt;Ghudson: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page describes opportunities for internal code cleanups.  Anything to do with a user-facing or developer-facing behavior should go elsewhere (perhaps in an RT ticket, or somewhere related to the roadmap).&lt;br /&gt;
&lt;br /&gt;
* sam2_process (preauth_sam2.c) should use a cleanup label instead of repeated free invocations.  It is also long and should be broken up into smaller pieces if possible.  (See [[Manual Testing]] for guidance on how to test at least part of this function.)&lt;br /&gt;
&lt;br /&gt;
* kadmind's main() should not have repeated blocks of calls to release resources.  It's probably unnecessary to release resources on error exit (plenty of other programs don't bother).&lt;br /&gt;
&lt;br /&gt;
* The build system used to have multiple configure.in files making use of an aclocal.m4.  Now that we only have one configure.in, we don't really need a separate aclocal.m4.&lt;br /&gt;
&lt;br /&gt;
* In the build system, some variables like INSTALL_PREFIX are just name variants of other variables and are only used in one or two places under the variant name.&lt;br /&gt;
&lt;br /&gt;
* Account lockout decision logic is duplicated in the DB2 and LDAP KDB modules.&lt;br /&gt;
&lt;br /&gt;
* The serialization framework has several levels of unnecessary nesting and should use a cleanup label rather than the repeated &amp;quot;if (!kret)&amp;quot; pattern.&lt;br /&gt;
&lt;br /&gt;
* lib/krb5/os appears to have a couple of different functions to generate ADDRTYPE_ADDRPORT addresses (one in mkfaddr.c and another in full_ipaddr.c).&lt;br /&gt;
&lt;br /&gt;
* klist and kinit (at least) still have some internal vestiges from when they supported krb4 and krb5 credentials, and could be simplified.&lt;br /&gt;
&lt;br /&gt;
* The kdcpreauth pluggable interface uses the new plugin support functions, but does not have a proper consumer interface as described in [[Projects/Plugin_support_improvements#Consumer_interface]].&lt;br /&gt;
&lt;br /&gt;
* It's no longer our practice to use krb5_x() to make calls through function pointers, but it's still used in ktfns.c.&lt;br /&gt;
&lt;br /&gt;
* The LDAP KDB module maintains a connection pool, but only ever uses one connection (since our KDC is single-threaded).&lt;br /&gt;
&lt;br /&gt;
* lib/gssapi/mechglue should use the MIT krb5 style, not the Solaris coding style with tabs.&lt;br /&gt;
&lt;br /&gt;
* lib/gssapi/generic contains some utility functions which are specific to the krb5 mech and should be located in lib/gssapi/krb5.&lt;br /&gt;
&lt;br /&gt;
* Some parameters in osconf.hin are unused (like KDC_PORTNAME, KRB5_DEFAULT_ADMIN_ACL, and DEFAULT_ADMIN_ACL).&lt;br /&gt;
&lt;br /&gt;
* kpropd's design can be simplified:&lt;br /&gt;
** Currently, it forks to handle each incoming connection, but then waits for the child process.  This could be done without forking, although doit() would have to be modified to avoid using exit() or an aborting SIGALRM handler.&lt;br /&gt;
** Currently kpropd relies on dual-stack support to handle both IPv4 and IPv6 connections so that it can use a single blocking accept() call to wait for incoming connections.  Some platforms such as OpenBSD don't have dual-stack support.  We should open a listening socket for each address family and use libverto to wait for connections on both of them.&lt;br /&gt;
** Currently, if iprop is enabled, a child process is used to handle incoming connections, but using libverto, the same process should be able to handle both.  The process wouldn't ask for iprop updates while processing a kprop connection (since that handling is synchronous), but that should be okay.&lt;br /&gt;
&lt;br /&gt;
* The libkdb5 interface includes krb5_db_setup_lib_handle(), which has no caller-visible semantics (it is invoked internally when needed).  That function can be removed from the interface, since we don't guarantee interface stability for that library.&lt;br /&gt;
&lt;br /&gt;
* krb5_db_get_age() and its associated DAL interface can be removed.&lt;br /&gt;
&lt;br /&gt;
* The krb5_db_entry &amp;quot;len&amp;quot; field has no caller-useful semantics.  krb5_db_put_principal will abort with the DB2 back end if the len field is not set to the magic value KRB5_KDB_V1_BASE_LENGTH.  This field and the associated constant can be removed.&lt;br /&gt;
&lt;br /&gt;
* The krb5_db_entry &amp;quot;n_tl_data&amp;quot; field is redundant with the length of the tl_data linked list, and isn't likely to have a significant performance impact since tl_data lists are short.  It can be removed.&lt;br /&gt;
&lt;br /&gt;
* The constants KRB5_TL_KADM5_E_DATA, KRB5_TL_RB1_CHALLENGE, KRB5_TL_USER_CERTIFICATE, KRB5_TL_LM_KEY, and KRB5_TL_X509_SUBJECT_ISSUER_NAME are unused and can likely be removed.&lt;br /&gt;
&lt;br /&gt;
* The osa_policy_ent_rec &amp;quot;version&amp;quot; field has no caller-visible semantics; it is used internally by the DB2 module's xdr_osa_policy_ent_rec(), but a local variable would serve.  The field can be removed.&lt;br /&gt;
&lt;br /&gt;
* adb_openclose.c maintains a static linked list mapping filenames to lock structures, in an attempt to work around bad POSIX file locking semantics.  This list serves no useful purpose because there is no equivalent code for the main DB2 lockfile, and OFD locks (where they are available) are a much better solution.  The list can be removed and the locking code simplified.&lt;br /&gt;
&lt;br /&gt;
* krb5_db_iter_policy takes a match_expr parameter and passes it through to the back end, but both back ends ignore it.  The parameter can be removed.&lt;br /&gt;
&lt;br /&gt;
* add_to_history() in svr_principal.c stores password history entries in a circular queue, which is unnecessarily complicated because the data structure is serialized after every password change.  We can simplify this code by always generating a list in sorted order, although we must remain bidirectionally compatible with the existing code.  We can either sort the entries in the structure we read in, or we can use the old_key_next value to identify which nhist-2 entries to preserve.&lt;br /&gt;
&lt;br /&gt;
* alt_prof.c contains functions for opening krb5.conf and kdc.conf, and for translating string, boolean, deltat, and integer values.  These are largely redundant with normal profile handling functions.  (One difference: alt_prof.c selects the last relation for a single-valued field, while regular profile functions select the first one.  This is probably ignorable.)&lt;br /&gt;
&lt;br /&gt;
* krb5_dbe_fetch_act_key_list is used only from kadmind, which immediately calls krb5_dbe_find_act_mkey and frees the list.  This API could be replaced with an API to retrieve the active master key and its kvno, so that kadmind does not need to know about the existence of the master key activation list.  The new API could also be used in kdb5_util's kdb5_update_princ_encryption in place of the three calls it uses to get the active master key.&lt;br /&gt;
&lt;br /&gt;
* krb5_free_cred_enc_part does not obey the usual contract, as it frees only the contents of the container passed in, not the container itself.  It is not a public API, so its behavior can be changed as long as all of the in-tree callers are adjusted to match.&lt;br /&gt;
&lt;br /&gt;
* krb5_rd_req_decoded and krb5_rd_req_decoded_anyflags have unnecessary output parameters which receive a copy of the ticket.  The ticket (with decrypted enc_part if we could decrypt it) is in req-&amp;gt;ticket, so the caller does not need a copy.  The following cleanups could simplify the code and slightly improve performance:&lt;br /&gt;
** krb5_rd_req could pass a NULL ticket argument, and instead steal the ticket pointer before freeing request.&lt;br /&gt;
** kg_accept_krb5 could pass a NULL ticket argument, and instead refer to request-&amp;gt;ticket (possibly via an alias pointer).&lt;br /&gt;
** kdc_rd_ap_req could have its ticket parameter removed.  kdc_process_tgs_req could refer to apreq-&amp;gt;ticket and could steal that pointer for its own ticket output parameter before freeing apreq.&lt;br /&gt;
** Since krb5_rd_req_decoded/krb5_rd_req_decoded_anyflags are no longer public interfaces (they were purged in the great 1.2.2 cleanup, and their prototypes are completely gone from krb5.h since 1.7), we could rename them and remove their ticket output parameters.&lt;br /&gt;
&lt;br /&gt;
* pkinit_crypto_openssl.h does not need to be a header file.  Its contents can be part of pkinit_crypto_openssl.c.&lt;br /&gt;
&lt;br /&gt;
* pkinit_identity_crypto_context contains a stack of certs (my_certs) and an index (cert_index), but the stack only ever contains one cert and the index is always 0.&lt;br /&gt;
&lt;br /&gt;
* pkinit_identity_crypto_context contains a cert collection with a different lifetime from the object itself, managed by crypto_load_certs() and crypto_free_cert_info().  The collection is only used briefly by pkinit_identity_initialize() and pkinit_identity_prompt().  It would be better represented with a separate object type, whose lifetime is managed via local variables in the pkinit_identity functions.&lt;br /&gt;
&lt;br /&gt;
* The PKINIT KDC and PKINIT client share a number of identity requirements such as anchors, intermediates, and CRLs, but they have rather different logic for certificates.  The client can select from a collection of certs and may need to prompt for passwords in order to access private keys.  The KDC never prompts for a password and has just one cert.  The KDC code path would be easier to understand if it did not go through all of the same identity initialization interface as the client, with the anchor/intermediate/CRL implementation shared between the two via a helper function.&lt;br /&gt;
&lt;br /&gt;
* If k5_vset_error allowed a null ep parameter and did nothing (like krb5_set_error_message allows a null context), then callers of the plugins.c functions could be simplified when they don't want extended error information, as in the g_initialize.c macros.&lt;br /&gt;
&lt;br /&gt;
* The libprofile iterator logic around skip_num is not very intuitive and may not always be correct.  iter-&amp;gt;num counts up when a match is returned--that is, deleted nodes are not considered.  If iter-&amp;gt;num is used for skip_num because the file generation has changed, it counts down in the search loop *before* deleted nodes are ignored.  This behavior is required for the first test in test_prof1 which deletes all nodes in an iterator, because the first call to profile_update_relation changes the file generation and also deletes the first matching node.&lt;br /&gt;
&lt;br /&gt;
* libprofile's prof_tree.c contains several copies of loops to search for a name in a node list, and its prof_set.c contains several copies of loops to look up parent sections.  These could be factored out; however, the skip_num logic in profile_node_iterator currently prevents factoring out that copy of the search loop unless skip_num becomes a parameter of the factored-out helper function.&lt;br /&gt;
&lt;br /&gt;
* lib/kadm5/srv/server_acl.c contains many opportunities for cleanup:&lt;br /&gt;
** The acl_*_msg string variables should be removed and their values inlined into the log statements.&lt;br /&gt;
** The ae_ prefix on acl_entry field names is unnecessary.&lt;br /&gt;
** The kadm5int_acl_ prefix on static functions is unnecessary.&lt;br /&gt;
** The name, target, and restrictions strings could be evaluated immediately at parsing time.&lt;br /&gt;
** A lot of code could be de-indented.&lt;br /&gt;
** The ae_name_bad, ae_target_bad, and ae_restrictions_bad fields are redundant, as setting any of them results in setting ae_name_bad which disables the entry.  They may wind up all being unnecessary if we stop doing lazy evaluation of those strings.&lt;br /&gt;
** The structure of kadm5int_acl_parse_restrictions makes it difficult to identify which part of the restrictions string is invalid.&lt;br /&gt;
** The file uses K&amp;amp;R-style function definitions.&lt;br /&gt;
** Several functions operate multiple times on their output arguments, contrary to current practice.&lt;br /&gt;
&lt;br /&gt;
* kadm5_policy_t is a typedef for char *, representing a policy name.  It is used in two prototypes in admin.h but not elsewhere.  It should be replaced with const char * in those prototypes, and the typedef should be commented as being deprecated.&lt;br /&gt;
&lt;br /&gt;
* krb5_string_to_deltat() is implemented in libkrb5 using a bison grammar, which adds to the complexity of our repository and build system.  It could be rewritten in C with no loss of clarity, as only a few interval formats are supported.&lt;br /&gt;
&lt;br /&gt;
* The library initialization support in k5-platform.h uses different strategies on Windows and POSIX platforms.  Windows (as of Vista and Server 2008) supports a function InitOnceExecuteOnce() which works like pthread_once().  Using that function we could make a Windows version of k5_once() and use the same library initialization strategy on all platforms.  Library finalization support would remain conditionalized by platform.&lt;br /&gt;
&lt;br /&gt;
* It is also possible to emulate static mutex initialization on Windows, using a wrapper lock function which does InterlockedCompareExchangePointer(), as detailed [http://stackoverflow.com/questions/3555859/is-it-possible-to-do-static-initialization-of-mutexes-in-windows here].  With static mutex initializers we might not need as many library initializers, although we would still need library finalizers to clean up any initialized mutexes.&lt;/div&gt;</summary>
		<author><name>Ghudson</name></author>	</entry>

	<entry>
		<id>https://k5wiki.kerberos.org/wiki?title=Coding_style/Practices&amp;diff=6039</id>
		<title>Coding style/Practices</title>
		<link rel="alternate" type="text/html" href="https://k5wiki.kerberos.org/wiki?title=Coding_style/Practices&amp;diff=6039"/>
				<updated>2023-07-22T22:11:23Z</updated>
		
		<summary type="html">&lt;p&gt;Ghudson: /* Misc. to be sorted */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__&lt;br /&gt;
==Quick Summary==&lt;br /&gt;
&lt;br /&gt;
* Avoid strcpy, strcat, sprintf, and *scanf.&lt;br /&gt;
* Use &amp;quot;goto cleanup&amp;quot; to ensure that resources are released on all function exit paths.&lt;br /&gt;
* Keep track of which pointers are owners and which are aliases; initialize owner pointers to NULL.&lt;br /&gt;
* Avoid creating structure instances containing a mix of owner and alias pointers.&lt;br /&gt;
* Name output variables ending with &amp;quot;_out&amp;quot;.  Initialize them at the beginning of a function, then don't touch them until just before successful return.&lt;br /&gt;
* Don't use assignments as truth values except (perhaps) in a while loop.&lt;br /&gt;
* Use NULL for the null pointer and '\0' for the null character.  Don't use pointers or characters as truth values.&lt;br /&gt;
* Put braces around flow control statement bodies if they are more than one line long, and around any do-while loop.&lt;br /&gt;
* Try to keep preprocessor statements outside of function bodies.&lt;br /&gt;
* Avoid declarations of local variables in inner scope.&lt;br /&gt;
* Parenthesize (sparingly) to avoid C precedence confusion, especially when using bitwise operators.&lt;br /&gt;
* Use all-uppercase names for macros.&lt;br /&gt;
* Avoid stepping on reserved C namespaces.&lt;br /&gt;
* Use the krb5_ prefix for libkrb5 API functions, and the k5_ prefix for linker-visible internal functions.  Don't use a prefix for static functions.&lt;br /&gt;
* Don't use designated initializers or compound literals in code which is built on Windows.&lt;br /&gt;
* Don't use variable-length arrays or alloca().&lt;br /&gt;
* Avoid long or deeply nested function bodies.  Use helpers to limit function complexity.&lt;br /&gt;
* Function calls through pointers should look like &amp;quot;(*fp)(args)&amp;quot; or &amp;quot;vtable-&amp;gt;method(vars)&amp;quot;.&lt;br /&gt;
* Always declare function return types.  Use ANSI C-style function definitions.&lt;br /&gt;
* Don't pass or return structures by value in API functions.&lt;br /&gt;
* Precede functions with block comments describing what they do.&lt;br /&gt;
* Make your code warning-clean under the gcc warning flags used in our build system.&lt;br /&gt;
&lt;br /&gt;
== String Handling ==&lt;br /&gt;
&lt;br /&gt;
Code should not use any of the following functions: strcpy, strcat, sprintf, or any *scanf function.&lt;br /&gt;
&lt;br /&gt;
Dynamically allocated buffers are preferred to fixed-sized buffers.  When using dynamic buffers:&lt;br /&gt;
* Use strdup or asprintf for simple constructions.&lt;br /&gt;
* Use the k5buf module (k5-buf.h) for complex constructions.  If this is not desirable, strlcpy and strlcat are valid alternatives.&lt;br /&gt;
&lt;br /&gt;
Substitute versions of strlcpy, strlcat, and asprintf, for operating systems that don't supply them, are declared in k5-platform.h and defined in the support library (which practically everything in the tree links directly against).&lt;br /&gt;
&lt;br /&gt;
When using fixed-sized buffers:&lt;br /&gt;
* Use strlcpy for simple copies.&lt;br /&gt;
* Use snprintf for simple compound constructions.  Avoid using precision or field width specifiers in snprintf format strings.&lt;br /&gt;
* To check for truncation when using snprintf, use the following approach:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
result = snprintf(buffer, sizeof(buffer), &amp;quot;format string&amp;quot;, ...);&lt;br /&gt;
if (SNPRINTF_OVERFLOW(result, sizeof(buffer))&lt;br /&gt;
    handle_overflow_error;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The SNPRINTF_OVERFLOW macro is defined in k5-platform.h.&lt;br /&gt;
&lt;br /&gt;
=== Current conformance ===&lt;br /&gt;
&lt;br /&gt;
Existing code mostly conforms, with some exceptions.&lt;br /&gt;
&lt;br /&gt;
=== Rationale ===&lt;br /&gt;
&lt;br /&gt;
It is relatively common to audit a code base such as krb5 and flag all uses of strcpy and similar functions, even if they are used safely.  Verifying that the function is used safely requires manual inspection.  Using safer alternatives does not guarantee code safety, but does reduce the likelihood of a catastrophic buffer overflow vulnerability.&lt;br /&gt;
&lt;br /&gt;
In some compilation environments under Solaris, field widths and precisions are computed using screen columns rather than bytes.&lt;br /&gt;
&lt;br /&gt;
sprintf returns a signed integer; buffer sizes are typically size_t (which is an unsigned type).  Comparing the two directly will result in a warning from some compilers, and has unpredictable semantics depending on the relative widths of int and size_t.  Also, some sprintf implementations, such as the one in Solaris prior to version 10, return -1 on a buffer overflow, whereas the C99 behavior returns the number of bytes which would have been written to the string.  The SNPRINTF_OVERFLOW macro uses casts to address both issues.&lt;br /&gt;
&lt;br /&gt;
The k5buf module safely allows multi-step string construction within fixed-size or dynamic buffers without performing an error check on each append, and without pre-computing lengths.  Errors need only be checked when the resulting string needs to be read or handed off to another function.&lt;br /&gt;
&lt;br /&gt;
== Exception Handling ==&lt;br /&gt;
&lt;br /&gt;
If a function allocates several resources and has many exit paths, use the following general structure when possible:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
    krb5_error_code ret;&lt;br /&gt;
    char *ptr1 = NULL;&lt;br /&gt;
    krb5_blah *ptr2 = NULL;&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
    ret = another_function(...);&lt;br /&gt;
    if (ret)&lt;br /&gt;
        goto cleanup;&lt;br /&gt;
...&lt;br /&gt;
cleanup:&lt;br /&gt;
    free(ptr1);&lt;br /&gt;
    krb5_free_blah(ptr2);&lt;br /&gt;
    return ret;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(free() and krb5_free_foo() functions will both accept NULL as input and do nothing.)  Simpler functions may use simpler control structures, but do not get to the point of freeing the same resource in several different places within a function depending on the exit path.  Do not use multiple exit labels.&lt;br /&gt;
&lt;br /&gt;
Unless constrained by an API standard such as GSSAPI, functions which can fail should return a krb5_error_code.  Error codes are defined in com_err tables, usually located in src/lib/krb5/error_tables.&lt;br /&gt;
&lt;br /&gt;
Functions can also set extended error messages using krb5_set_error_message() (or, in dependencies of libkrb5, krb5int_set_error() on &amp;amp;context-&amp;gt;err).  Code should set extended error messages when an error condition is moderately likely to occur and the default string for the error code is insufficiently clear.  Avoid exposing function names and other implementation details in error messages.&lt;br /&gt;
&lt;br /&gt;
After ignoring or handling an error code, krb5_clear_error_message() (or krb5int_clear_error()) should be used to ensure that an extended error message is not applied erroneously to a later instance of the same error code.  This can be especially important in loops.&lt;br /&gt;
&lt;br /&gt;
=== Current conformance ===&lt;br /&gt;
&lt;br /&gt;
Existing code mostly conforms, with some exceptions.&lt;br /&gt;
&lt;br /&gt;
=== Rationale ===&lt;br /&gt;
&lt;br /&gt;
The &amp;quot;goto cleanup&amp;quot; flow control is the most reliable way to avoid resource leaks within the constraints of the krb5 code base.  Within libraries, the code base does not abort on memory allocation failure, so tends to have many exit paths within some functions.&lt;br /&gt;
&lt;br /&gt;
Extended error messages can provide invaluable information about error conditions, but merely serve to expand code if used mechanically.&lt;br /&gt;
&lt;br /&gt;
== Memory management ==&lt;br /&gt;
&lt;br /&gt;
An allocated object can have multiple pointers to it.  The pointer through which the object will eventually be freed is called the owner, and other pointers to the object are called aliases.  The owner may change over the lifetime of the object.&lt;br /&gt;
&lt;br /&gt;
When transferring ownership of a pointer (such as when returning an allocated value to a caller via an output parameter), null out the old owner pointer unless it is about to be destroyed or go out of scope.&lt;br /&gt;
&lt;br /&gt;
Avoid mixing owner pointers and aliases within a structure.  Create additional local variables to act as owner pointers when this situation occurs.&lt;br /&gt;
&lt;br /&gt;
Initialize variables containing owner pointers to NULL.  Free the pointed-to objects (unconditionally, when possible) in the function's cleanup handler.&lt;br /&gt;
&lt;br /&gt;
In some cases these rules may not be reasonable; for instance, temporary memory allocated within a loop body must be freed within the loop body, not in the cleanup handler.  Break these rules when necessary, but also make liberal use of helper functions to simplify memory management.&lt;br /&gt;
&lt;br /&gt;
=== Current conformance ===&lt;br /&gt;
&lt;br /&gt;
Newer code mostly conforms; older code does not.&lt;br /&gt;
&lt;br /&gt;
=== Rationale ===&lt;br /&gt;
&lt;br /&gt;
Following these rules makes it easier to verify that a function contains no memory leaks, no double frees, and no dereferences after frees.  These rules also keep memory management logic out of the core logic of a function, making it easier to understand.&lt;br /&gt;
&lt;br /&gt;
== Output parameter handling ==&lt;br /&gt;
&lt;br /&gt;
Output parameter names should typically end in &amp;quot;_out&amp;quot;.  Output parameters should typically be the last parameters to a function, with certain exceptions (such as context-like parameters).&lt;br /&gt;
&lt;br /&gt;
Avoid filling in a caller-allocated structure.  Instead, allocate the structure within the function and output a pointer to the structure.&lt;br /&gt;
&lt;br /&gt;
If a function has output parameters, their values should be defined in all cases, including on failure.  Most of the time, this means setting output parameters to NULL or zero at the beginning of the function, and not assigning real values to the output parameters until successful completion from the function is guaranteed.  A typical function with output parameters should look something like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
krb5_error_code&lt;br /&gt;
function_with_output_param(type *input_param, type *ptr_out)&lt;br /&gt;
{&lt;br /&gt;
  krb5_error_code ret;&lt;br /&gt;
  type *ptr = NULL;&lt;br /&gt;
&lt;br /&gt;
  *ptr_out = NULL;&lt;br /&gt;
&lt;br /&gt;
  stuff that can go wrong here, allocating ptr;&lt;br /&gt;
&lt;br /&gt;
  *ptr_out = ptr;&lt;br /&gt;
  ptr = NULL;&lt;br /&gt;
&lt;br /&gt;
cleanup:&lt;br /&gt;
  free_function(ptr);&lt;br /&gt;
  other cleanup code here;&lt;br /&gt;
  return ret;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Simple wrapper functions can delegate the initialization of output paremeters to the functions they wrap, ''unless'' they are invoking the wrapped function through a function pointer.&lt;br /&gt;
&lt;br /&gt;
=== Current conformance ===&lt;br /&gt;
&lt;br /&gt;
Existing code mostly does not conform.  Filling in caller-allocated structures is common (though far from universal) in the public libkrb5 API.&lt;br /&gt;
&lt;br /&gt;
=== Rationale ===&lt;br /&gt;
&lt;br /&gt;
Naming output parameters with an &amp;quot;_out&amp;quot; suffix helps readers easily identify them, and also makes it clearer when a resource's ownership is transferred to the caller.  Since output parameters are only used near the beginning and end of a function, the extra verbosity is not very burdensome.&lt;br /&gt;
&lt;br /&gt;
Initializing output parameters makes it clear to static analysis tools that the previous value of the output parameter will not be used.  If there happens to be a bug in the function such that it returns success but does not set output parameters, or in the caller such that it uses an output parameter even though the function returned failure, then the bug will result in predictable behavior (generally a NULL pointer dereference) with no security consequences beyond a denial of service attack.&lt;br /&gt;
&lt;br /&gt;
== Assignments as truth values ==&lt;br /&gt;
&lt;br /&gt;
Do not use assignments as truth values.  Rather than this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/* bad style */&lt;br /&gt;
if ((ret = krb5_foo()))&lt;br /&gt;
    /* ... */;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
do this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/* better style */&lt;br /&gt;
ret = krb5_foo();&lt;br /&gt;
if (ret)&lt;br /&gt;
    /* ... */;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Current conformance ===&lt;br /&gt;
&lt;br /&gt;
Existing code varies widely.&lt;br /&gt;
&lt;br /&gt;
=== Rationale ===&lt;br /&gt;
&lt;br /&gt;
This makes the code easier to read, and also makes it easier to use&lt;br /&gt;
debuggers.  It may be excusable to put assignments into the&lt;br /&gt;
conditional espression of a &amp;quot;while&amp;quot; statement, though, like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
while ((ch = getopt(argc, argv, &amp;quot;abn&amp;quot;)) != -1)&lt;br /&gt;
    /* ... */;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Using assignments as truth values in conditional expressions (&amp;quot;ternary expressions&amp;quot;) may make&lt;br /&gt;
code particularly impenetrable.&lt;br /&gt;
&lt;br /&gt;
== The many names of zero ==&lt;br /&gt;
&lt;br /&gt;
There are at least three types of &amp;quot;zero&amp;quot; known to C.  These are the&lt;br /&gt;
integer zero (0), the null pointer constant (NULL), and the character&lt;br /&gt;
constant zero ('\0').  Yes, these are usually all technically the&lt;br /&gt;
integer zero.  Use them in their correct contexts.  (Purists will&lt;br /&gt;
point out that 0 is a valid null pointer constant; still, do not use 0&lt;br /&gt;
to specify a null pointer constant.  For further unconfusion, read the&lt;br /&gt;
section on null pointer constants in the comp.lang.c FAQ.)  Do not use a lone&lt;br /&gt;
variable as a truth value unless it's of integer type.  Thus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
int i;&lt;br /&gt;
char *cp;&lt;br /&gt;
/* ... */&lt;br /&gt;
if (i)&lt;br /&gt;
    /* ... */;&lt;br /&gt;
if (cp != NULL) {&lt;br /&gt;
    while (*cp != '\0')&lt;br /&gt;
        /* ... */;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Do not cast uses of NULL unless you're calling a function with a&lt;br /&gt;
variable number of arguments, in which case you should cast it to to&lt;br /&gt;
the appropriate pointer type.  (NULL may be defined as 0, and an integer 0&lt;br /&gt;
may not be the same size in the argument list as a pointer on a 64-bit&lt;br /&gt;
platform.)  Likewise, do not cast the return value&lt;br /&gt;
from malloc() and friends; the prototype should declare them properly&lt;br /&gt;
as returning a void&amp;amp;nbsp;* and thus shouldn't require an explicit cast.&lt;br /&gt;
&lt;br /&gt;
In any case, reading the section in the C FAQ on null pointers is&lt;br /&gt;
highly recommended to remove confusion regarding null pointers in C,&lt;br /&gt;
since this is a subject of much confusion to even experienced&lt;br /&gt;
programmers.  In particular, if you do not understand why using&lt;br /&gt;
calloc() to allocate a struct that contains pointer members or why&lt;br /&gt;
calling memset() to initialize such a struct to all-bytes-zero is&lt;br /&gt;
wrong, reread that section again.  Due to the prevalence of this practice and the practical difficulties of eliminating it, our [[portability assumptions]] currently require that platforms represent null pointers as all-bits-zero.&lt;br /&gt;
&lt;br /&gt;
== Brace placement ==&lt;br /&gt;
&lt;br /&gt;
Control flow statements that have a single statement as their body&lt;br /&gt;
should nevertheless have braces around their bodies if the body is&lt;br /&gt;
more than one line long, especially in the case of stacked multiple&lt;br /&gt;
if-else clauses; use:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
if (x) {&lt;br /&gt;
    if (y)&lt;br /&gt;
        foo();&lt;br /&gt;
    else&lt;br /&gt;
        bar();&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
instead of:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/* bad style */&lt;br /&gt;
if (x)&lt;br /&gt;
    if (y)&lt;br /&gt;
        foo();&lt;br /&gt;
    else&lt;br /&gt;
        bar();&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
which, while legible to the compiler, may confuse human readers and&lt;br /&gt;
make the code less maintainable, especially if new branches get added&lt;br /&gt;
to any of the clauses.&lt;br /&gt;
&lt;br /&gt;
If you are writing a do-while loop that has only one statement in its&lt;br /&gt;
body, put braces around it anyway, since the while clause may be&lt;br /&gt;
mistaken for a while loop with an empty body.  Don't do this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/* bad style */&lt;br /&gt;
do&lt;br /&gt;
    foo();&lt;br /&gt;
while (x);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Instead, write this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/* better style */&lt;br /&gt;
do {&lt;br /&gt;
    foo();&lt;br /&gt;
} while (x);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Preprocessor conditionals ==&lt;br /&gt;
&lt;br /&gt;
Instead of scattering &amp;lt;code&amp;gt;#ifdef&amp;lt;/code&amp;gt; or other preprocessor conditionals throughout the code use preprocessor conditionals to control the definition of a function-like macro, or similar construct, which is used instead of embedded preprocessor conditionals in code.&lt;br /&gt;
&lt;br /&gt;
Instead of this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    do_something();&lt;br /&gt;
    /* bad style */&lt;br /&gt;
#ifdef DEBUG&lt;br /&gt;
    fprintf(stderr, &amp;quot;did something\n&amp;quot;);&lt;br /&gt;
#endif&lt;br /&gt;
    do_something_else();&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
do something more like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#ifdef DEBUG&lt;br /&gt;
#define DPRINTF(x) fprintf(stderr, x)&lt;br /&gt;
#else&lt;br /&gt;
#define DPRINTF(x)		/* empty */&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
/* ... */&lt;br /&gt;
&lt;br /&gt;
    do_something();&lt;br /&gt;
    /* better style */&lt;br /&gt;
    DPRINTF((&amp;quot;did something\n&amp;quot;));&lt;br /&gt;
    do_something_else();&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Do not intersperse conditional compilation&lt;br /&gt;
directives with control flow statements, as some combination of&lt;br /&gt;
&amp;lt;code&amp;gt;#define&amp;lt;/code&amp;gt;d symbols may result in statements getting eaten by dangling&lt;br /&gt;
bits of control flow statements.  When it is not possible to avoid&lt;br /&gt;
this questionable practice (you really should rewrite the relevant&lt;br /&gt;
code section), make use of redundant braces to make a compiler&lt;br /&gt;
error more likely than incorrect runtime behavior (such as&lt;br /&gt;
inadvertently providing someone with a root shell -- this has actually happened, long ago).&lt;br /&gt;
&lt;br /&gt;
Do not intersperse conditional compilation directives with control&lt;br /&gt;
flow statements in such a way that confuses emacs cc-mode.  Not only&lt;br /&gt;
does emacs get confused, but the code becomes more difficult to read&lt;br /&gt;
and maintain.  Therefore, avoid code like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    /* bad style */&lt;br /&gt;
    if (x) {&lt;br /&gt;
        f();&lt;br /&gt;
    }&lt;br /&gt;
#ifdef FOO&lt;br /&gt;
    else if (y) {&lt;br /&gt;
#else&lt;br /&gt;
    else {&lt;br /&gt;
#endif&lt;br /&gt;
        g();&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Put comments after conditional compilation directives such as &amp;quot;#else&amp;quot;&lt;br /&gt;
and &amp;quot;#endif&amp;quot;.  Make them correspond to the sense of the value that&lt;br /&gt;
controls the compilation of the section they are closing, i.e.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#ifdef FOO&lt;br /&gt;
/* ... */&lt;br /&gt;
#else /* !FOO */&lt;br /&gt;
/* ... */&lt;br /&gt;
#endif /* !FOO */&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Also, in the case of more complex conditional compilation directives,&lt;br /&gt;
write the comments like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#if defined(FOO) || defined(BAR)&lt;br /&gt;
/* ... */&lt;br /&gt;
#else /* !(defined(FOO) || defined(BAR)) */&lt;br /&gt;
/* ... */&lt;br /&gt;
#endif /* !(defined(FOO) || defined(BAR)) */&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Conformance ===&lt;br /&gt;
&lt;br /&gt;
Existing code mostly does not conform.&lt;br /&gt;
&lt;br /&gt;
=== Rationale ===&lt;br /&gt;
&lt;br /&gt;
Instances of &amp;quot;ifdef soup&amp;quot; make code more difficult to read, and make it more difficult to recognize bugs.  It also interferes with automated reformatting and analysis tools.&lt;br /&gt;
&lt;br /&gt;
== Local variables ==&lt;br /&gt;
&lt;br /&gt;
Do not declare variables in an inner scope, e.g. inside the compound&lt;br /&gt;
substatement of an if statement, unless the complexity of the code&lt;br /&gt;
really demands that the variables be declared that way.  In such&lt;br /&gt;
situations, the function could probably stand to be broken up into&lt;br /&gt;
smaller chunks anyway.  Do not declare variables in an inner scope&lt;br /&gt;
that shadow ones in an outer scope, since this leads to confusion.&lt;br /&gt;
Also, some debugging environments, such as gdb under Solaris, can't&lt;br /&gt;
see variables declared in an inner scope, so declaring such variables&lt;br /&gt;
will make maintenance more difficult as well.&lt;br /&gt;
&lt;br /&gt;
== Placement of parentheses ==&lt;br /&gt;
&lt;br /&gt;
Parenthesize expressions that may be confusing, particularly where C's&lt;br /&gt;
precedences are broken.  For example, the shift operators have lower&lt;br /&gt;
precedence than the +, -, *, /, and % operators.  Perhaps the most&lt;br /&gt;
familiar C precedence quirk is that equality and relational operators&lt;br /&gt;
are of higher precedence than assignment operators.  Less well known&lt;br /&gt;
is that the bitwise operators are of a lower precedence than equality&lt;br /&gt;
and relational operators.&lt;br /&gt;
&lt;br /&gt;
The sizeof operator takes either a unary expression or a parenthesized&lt;br /&gt;
type name.  It is not necessary to parenthesize the operand of sizeof&lt;br /&gt;
if it is applied to a unary expression, but still, always parenthesize&lt;br /&gt;
the operand of the sizeof operator.  The sizeof operator does not&lt;br /&gt;
evaluate its operand if it is a unary expression, so usages such as&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
s = sizeof(++foo);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
should be avoided for the sake of sanity and readability.&lt;br /&gt;
&lt;br /&gt;
== Function-like macros ==&lt;br /&gt;
&lt;br /&gt;
Macros should have all-uppercase names.  If it is necessary to use&lt;br /&gt;
multiple statements, use braces, and wrap the whole thing in a&lt;br /&gt;
do-while(0) construct, such as&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#define FOOMACRO(x, y) do {                     \&lt;br /&gt;
    foo = (x) + (y);                            \&lt;br /&gt;
    f(y);                                       \&lt;br /&gt;
} while (0)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Leave off the semicolon at the end of a function-like macro, so that&lt;br /&gt;
it can be mostly used like a call to a function without a return&lt;br /&gt;
value.  Line up the backslashes to make it more readable.  Use M-x&lt;br /&gt;
c-backslash-region in emacs to do neat lined-up backslashes.&lt;br /&gt;
Parenthesize uses of arguments in the replacement text of a macro in&lt;br /&gt;
order to prevent weird interactions.&lt;br /&gt;
&lt;br /&gt;
== Namespaces ==&lt;br /&gt;
&lt;br /&gt;
The C standard reserves a bunch of namespaces for the implementation.&lt;br /&gt;
Don't stomp on them.  For practical purposes, any identifier with a&lt;br /&gt;
leading underscore should not be used.  (Technically, ^_[a-z].* are&lt;br /&gt;
reserved only for file scope, so should be safe for things smaller&lt;br /&gt;
than file scope, but it's better to be paranoid in this case.)&lt;br /&gt;
&lt;br /&gt;
POSIX reserves typedef names ending with _t as well.&lt;br /&gt;
&lt;br /&gt;
Recall that errno is a reserved identifier, and is permitted to be a&lt;br /&gt;
macro.  Therefore, do not use errno as the name of a structure member,&lt;br /&gt;
etc.&lt;br /&gt;
&lt;br /&gt;
Reserved namespaces are somewhat more restricted than this; read the&lt;br /&gt;
appropriate section of the C standard if you have questions.&lt;br /&gt;
&lt;br /&gt;
If you're writing new library code, pick a short prefix and stick with&lt;br /&gt;
it for any identifier with external linkage.  If for some reason a&lt;br /&gt;
library needs to have external symbols that should not be visible to&lt;br /&gt;
the application, pick another (related) prefix to use for the internal&lt;br /&gt;
globals.  This applies to typedef names, tag names, and preprocessor&lt;br /&gt;
identifiers as well.&lt;br /&gt;
&lt;br /&gt;
For the krb5 library, the prefix for public global symbols is &amp;quot;krb5_&amp;quot;.&lt;br /&gt;
Use &amp;quot;k5_&amp;quot; as a prefix for library internal globals.  Avoid using &amp;quot;__&amp;quot;&lt;br /&gt;
in symbol names, as it may confuse C++ implementations.  There are&lt;br /&gt;
admittedly a number of places where we leak thing into the namespace;&lt;br /&gt;
we should try to fix these.&lt;br /&gt;
&lt;br /&gt;
Header files should also not leak symbols.  Usually using the upcased&lt;br /&gt;
version of the prefix you've picked will suffice, e.g. &amp;quot;KRB5_&amp;quot; as a&lt;br /&gt;
CPP symbol prefix corresponding to &amp;quot;krb5_&amp;quot;.  In general, do not define&lt;br /&gt;
macros that are lowercase, in order to avoid confusion and to prevent&lt;br /&gt;
namespace collisions.&lt;br /&gt;
&lt;br /&gt;
Do not formulaically apply prefixes such as krb5_ or krb5int_ to static&lt;br /&gt;
function names.  It is better for static functions to have short&lt;br /&gt;
descriptive, and it can be confusing to see the krb5_ prefix on a symbol&lt;br /&gt;
which is not actually part of the krb5 API.&lt;br /&gt;
&lt;br /&gt;
The C standard only guarantees six case-insensitive characters to be&lt;br /&gt;
significant in external identifiers; this is largely regarded as&lt;br /&gt;
obsolescent even in 1989 and we will ignore it.  It does, however,&lt;br /&gt;
only guarantee 31 case-sensitive characters to be signficant in&lt;br /&gt;
internal identifiers, so do not use identifiers that differ beyond the&lt;br /&gt;
31st character.  This is unlikely to be a problem, though.&lt;br /&gt;
&lt;br /&gt;
== Function length ==&lt;br /&gt;
&lt;br /&gt;
Functions should not be longer than about 60 lines.  Strongly consider breaking up functions that are longer than this limit.&lt;br /&gt;
&lt;br /&gt;
=== Conformance ===&lt;br /&gt;
&lt;br /&gt;
Existing code conforms somewhat, with some egregious exceptions.  Some functions exceed 500 lines in length.  Older internal library symbols use &amp;quot;krb5int_&amp;quot; as a prefix instead of &amp;quot;k5_&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
=== Rationale ===&lt;br /&gt;
&lt;br /&gt;
Functions that are excessively lengthy are difficult to read.  Especially when the beginning of a control structure does not fit on the same screen or page as its end, maintenance can become problematic.  60 lines is about the maximum length that can comfortably fit on a sheet of letter-sized paper.&lt;br /&gt;
&lt;br /&gt;
== Nesting depth ==&lt;br /&gt;
&lt;br /&gt;
The maximum indentation level should not be more than four.  Deeply nested control flow generally indicates that a function needs to be broken into smaller pieces.&lt;br /&gt;
&lt;br /&gt;
=== Conformance ===&lt;br /&gt;
&lt;br /&gt;
Existing code conforms somewhat.&lt;br /&gt;
&lt;br /&gt;
=== Rationale ===&lt;br /&gt;
&lt;br /&gt;
Deeply nested control flow is difficult to read.&lt;br /&gt;
&lt;br /&gt;
== Copyright/License Statements ==&lt;br /&gt;
&lt;br /&gt;
Each applicable copyright/license statement for a file should appear by itself in a block comment.  Copyright/license statements should appear near the top of source files, after any emacs formatting or filename comments but before any descriptive comments or non-comment lines of source code.  See prototype/prototype.c and prototype/prototype.h for a more detailed example.&lt;br /&gt;
&lt;br /&gt;
All unique (except for year) copyright/license statements should appear in the top-level NOTICE file.&lt;br /&gt;
&lt;br /&gt;
=== Conformance ===&lt;br /&gt;
&lt;br /&gt;
Existing code mostly conforms, except that copyright/license statements do not usually appear by themselves in block comments.  In a few cases copyright/license statements appear later on in source files and should be moved to the top.&lt;br /&gt;
&lt;br /&gt;
=== Rationale ===&lt;br /&gt;
&lt;br /&gt;
Formatting license comments this way allows them to be extracted from source code by scripts, without the need for ugly markers.  The top-level NOTICE file makes it easier to satisfy the documentation requirements of licenses and to determine all of the terms under which MIT Kerberos may be used.&lt;br /&gt;
&lt;br /&gt;
== C99 features ==&lt;br /&gt;
&lt;br /&gt;
Use static inline functions instead of macros where possible.  Variadic macros may be used when needed.&lt;br /&gt;
&lt;br /&gt;
Where fixed-width integer types are required, use types from &amp;lt;stdint.h&amp;gt; such as int32_t.  Where an integer type of at least 64 bits is required, use &amp;quot;long long&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Do not use designated initializers or compound literals in code which is built on Windows.  They may be used in code which is not built on Windows.&lt;br /&gt;
&lt;br /&gt;
Avoid using declarations after statements (see [[#Local Variables | Local Variables]]).  Absolutely do not use them in code which is built on Windows.&lt;br /&gt;
&lt;br /&gt;
Do not use variable-length arrays or alloca().&lt;br /&gt;
&lt;br /&gt;
Do not use // comments (see [[Coding_style/Formatting#Comment Formatting | Comment Formatting]]).&lt;br /&gt;
&lt;br /&gt;
=== Conformance ===&lt;br /&gt;
&lt;br /&gt;
Older code uses Kerberos-specific fixed-width integer types such as krb5_int32.  Types from &amp;lt;stdint.h&amp;gt; can be used interchangeably with these types while we migrate away from them.&lt;br /&gt;
&lt;br /&gt;
=== Rationale ===&lt;br /&gt;
&lt;br /&gt;
At this time, official builds of Kerberos for Windows are performed using Visual Studio 2010, which supports only a subset of C99 features (see [[Portability research]]).  Support for the inline keyword is ensured by &amp;lt;win-mac.h&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Variable-length arrays are unsafe because there is no error checking.  If the length can be controlled by an attacker, security-critical bugs may result.&lt;br /&gt;
&lt;br /&gt;
== Misc. to be sorted ==&lt;br /&gt;
&lt;br /&gt;
Assume, for most purposes, working ANSI/ISO C ('89, not '99) support,&lt;br /&gt;
both for internal use and for applications compiling against Kerberos&lt;br /&gt;
header files and libraries.  Some exceptions are noted below.&lt;br /&gt;
&lt;br /&gt;
When calling a function through a variable which holds a function&lt;br /&gt;
pointer, explicitly deference the variable in order to make it easy&lt;br /&gt;
to see that the call is through a function pointer.  Do not explicitly&lt;br /&gt;
dereference the pointer if it is contained within a structure or union,&lt;br /&gt;
since there is no ambiguity in that case.  Do not explicitly take the&lt;br /&gt;
address of a function in order to assign it to a function pointer.&lt;br /&gt;
Thus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
int (*fp)(void);&lt;br /&gt;
int foofunc(void);&lt;br /&gt;
fp = foofunc;&lt;br /&gt;
x = (*fp)();&lt;br /&gt;
x = vtable.funcname();&lt;br /&gt;
x = vtable-&amp;gt;funcname();&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In general, do not take the address of an array.  It does not return a&lt;br /&gt;
pointer to the first element; it returns a pointer to the array&lt;br /&gt;
itself.  These are often identical when cast to an integral type, but&lt;br /&gt;
they are inherently of different types themselves.  Functions that&lt;br /&gt;
take array types or pointers to array types as arguments can be&lt;br /&gt;
particularly trouble-prone.&lt;br /&gt;
&lt;br /&gt;
If a function is declared to return a value, do not call &amp;quot;return&amp;quot;&lt;br /&gt;
without an argument or allow the flow of control to fall off the end&lt;br /&gt;
of the function.&lt;br /&gt;
&lt;br /&gt;
Always declare the return type of a function, even if it returns int.&lt;br /&gt;
Yes, this means declaring main() to return int, since main() is&lt;br /&gt;
required to return int by the standard.  If a function is not supposed&lt;br /&gt;
to return a value, declare it as returning void rather than omitting&lt;br /&gt;
the return type, which will default the return type to int.&lt;br /&gt;
&lt;br /&gt;
Use ANSI C prototype-style function declarations and definitions.  For functions with no parameters, use &amp;quot;(void)&amp;quot; in both the declaration and definition.&lt;br /&gt;
&lt;br /&gt;
Don't pass or return structures in API functions except by address.&lt;br /&gt;
&lt;br /&gt;
Every function should have a block comment describing briefly in complete sentences what it does, what inputs and outputs it has, and what error codes it can return.  It should also describe any unusual aspects of the function.  If the function is prototyped in a header file, the block comment should precede the prototype in the header file; otherwise it should precede the function definition.&lt;br /&gt;
&lt;br /&gt;
Strive to make your code capable of compiling using &amp;quot;gcc -Wall&lt;br /&gt;
-Wmissing-prototypes -Wtraditional -Wcast-align&lt;br /&gt;
-pedantic&amp;quot; [XXX need to rethink this&lt;br /&gt;
somewhat] without generating any errors or warnings.  Do not, however,&lt;br /&gt;
compile using the &amp;quot;-ansi&amp;quot; flag to gcc, since that can result in odd&lt;br /&gt;
behavior with header files on some systems, causing some necessary&lt;br /&gt;
symbols to not be defined.&lt;/div&gt;</summary>
		<author><name>Ghudson</name></author>	</entry>

	<entry>
		<id>https://k5wiki.kerberos.org/wiki?title=Release_engineering_notes&amp;diff=6038</id>
		<title>Release engineering notes</title>
		<link rel="alternate" type="text/html" href="https://k5wiki.kerberos.org/wiki?title=Release_engineering_notes&amp;diff=6038"/>
				<updated>2023-07-06T18:44:09Z</updated>
		
		<summary type="html">&lt;p&gt;Ghudson: /* Pulling up changes to release branches */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Release engineering environment==&lt;br /&gt;
&lt;br /&gt;
Release engineering operations are currently performed on a Ubuntu 18.04 host.  Updates to the Ubuntu version may cause churn in the generated files which are checked into the repository due to newer versions of programs in the toolchain.&lt;br /&gt;
&lt;br /&gt;
The release engineering host must have the following packages installed:&lt;br /&gt;
&lt;br /&gt;
* autoconf&lt;br /&gt;
* bison&lt;br /&gt;
* build-essential&lt;br /&gt;
* dejagnu&lt;br /&gt;
* doxygen&lt;br /&gt;
* flex&lt;br /&gt;
* git&lt;br /&gt;
* keyutils&lt;br /&gt;
* ldap-utils&lt;br /&gt;
* libcmocka-dev&lt;br /&gt;
* libkeyutils-dev&lt;br /&gt;
* libldap2-dev&lt;br /&gt;
* liblmdb-dev&lt;br /&gt;
* libresolv-wrapper&lt;br /&gt;
* libsasl2-dev&lt;br /&gt;
* libssl-dev&lt;br /&gt;
* libtool&lt;br /&gt;
* pkg-config&lt;br /&gt;
* python-sphinx&lt;br /&gt;
* python-cheetah&lt;br /&gt;
* rcs&lt;br /&gt;
* slapd&lt;br /&gt;
* tcl-dev&lt;br /&gt;
* texlive&lt;br /&gt;
* texlive-latex-extra&lt;br /&gt;
&lt;br /&gt;
==Pulling up changes to release branches==&lt;br /&gt;
&lt;br /&gt;
* For each supported release (usually the most recent and one previous release), prepare a git working copy with the krb5-x.y branch checked out from the authoritative repository.  From the krbdev-services repository, copy githooks/hookutils.py and githooks-client/prepare-commit-msg into .git/hooks for both working copies.&lt;br /&gt;
&lt;br /&gt;
* Check that each working copy is clean, has no unexpected extra commits, and is up to date with the authoritative repository.  Checking the output of &amp;quot;git status&amp;quot; and running &amp;quot;git pull&amp;quot; should accomplish this.&lt;br /&gt;
&lt;br /&gt;
* At https://krbdev.mit.edu:444/rt/ , start a new search, add the term &amp;quot;queue is krb5&amp;quot;, then the criteria &amp;quot;tags is pullup&amp;quot;, then search.  It can be useful to create a browser tab for each search result.&lt;br /&gt;
&lt;br /&gt;
* If there has been a calendar year change since the last patch release, pull up the commit(s) which bump the project-wide copyright years as well.&lt;br /&gt;
&lt;br /&gt;
* For each release branch:&lt;br /&gt;
** For each ticket marked for pullup to that branch:&lt;br /&gt;
*** For each commit listed in the ticket, run &amp;quot;KRB5_VERSION_FIXED=x.y.z git cherry-pick -x COMMIT&amp;quot;, and address any merge conflicts.  x.y.z should be the next patch release that will be created on the release branch.  If there are merge conflicts, &amp;quot;git cherry-pick --continue&amp;quot; will not apply the log message hook, so edit the RT fields manually.&lt;br /&gt;
*** Examine the commits any consider any possible interactions with changes made since the release branch.&lt;br /&gt;
*** Run &amp;quot;make&amp;quot; and &amp;quot;make check&amp;quot;.  Remember that &amp;quot;make check&amp;quot; will not work for multiple working directories concurrently on the same host.&lt;br /&gt;
*** If the change isn't covered by automated tests, consider testing it by hand.&lt;br /&gt;
* Consider pushing the updated release branches to a personal github fork and waiting for Github Actions to finish building and testing it.&lt;br /&gt;
* If the pulled up changes are substantial, consider running a build and check of each release branch on krbdev-sparc-build.&lt;br /&gt;
* Push the updated release branches to the authoritative repository.&lt;br /&gt;
* Remove the &amp;quot;pullup&amp;quot; tag from each ticket.  This can be done in a bulk update from the search result page, or it can be done on each ticket individually from the jumbo page.&lt;br /&gt;
&lt;br /&gt;
==Creating a new release branch==&lt;br /&gt;
&lt;br /&gt;
* At https://krbdev.mit.edu:444/rt/ , go to Admin -&amp;gt; Custom Fields -&amp;gt; Target_version and add x.y and x.y-next values.  Do the same for Version_Fixed.&lt;br /&gt;
* At https://krbdev.mit.edu:444/rt/ , perform a search with the following criteria:&lt;br /&gt;
** Queue is krb5&lt;br /&gt;
** Status is resolved&lt;br /&gt;
** Version_Fixed is (no value)&lt;br /&gt;
** Tags is not unsupported&lt;br /&gt;
** Tags is not noresource&lt;br /&gt;
** Tags is not nochange&lt;br /&gt;
* Verify that the resulting list of tickets are all for changes introduced in the past development cycle, and bulk update them to have Version_Fixed x.y.&lt;br /&gt;
* On the master branch, update doc/mitK5features.rst, updating the &amp;quot;Latest stable&amp;quot; and &amp;quot;Supported&amp;quot; release numbers.  Write up a list of major changes for the new release, broken down by category.  Code quality changes usually do not have associated tickets, so review the version history for commits with no RT headers.  Commit with the subject &amp;quot;Update features list for x.y&amp;quot;.&lt;br /&gt;
* On the master branch, update &amp;lt;code&amp;gt;config.guess&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;config.sub&amp;lt;/code&amp;gt; from &amp;lt;code&amp;gt;git://git.savannah.gnu.org/config.git&amp;lt;/code&amp;gt;.  Commit with the subject &amp;quot;Update config.guess, config.sub&amp;quot;&lt;br /&gt;
* On the master branch, run &amp;quot;make regen&amp;quot;.  Commit with the subject &amp;quot;make regen&amp;quot;.  Push the master branch to the authoritative repository.&lt;br /&gt;
* Create the new branch and push it to the authoritative repository.&lt;br /&gt;
* On the new branch, update README for the new release:&lt;br /&gt;
** Make sure that all x.y references are for the new version (they should be already).&lt;br /&gt;
** Update any notes about transitions (such as enctype deprecations) and add new ones if necessary.&lt;br /&gt;
** Include the list of major changes for the new release.&lt;br /&gt;
** Include the list of tickets changed (copy-paste from https://krbdev.mit.edu/rt/NoAuth/krb5-x.y/fixed-x.y.z.html).&lt;br /&gt;
** Copy the list of contributors from the previous release branch.&lt;br /&gt;
** Add contributors from the RT tickets for the new release branch.&lt;br /&gt;
** Commit with the message &amp;quot;Update README for krb5-x.y&amp;quot; and push to the authoritative repository.&lt;br /&gt;
* On the master branch, update README for the next prerelease:&lt;br /&gt;
** In README, update x.y references to x.(y+1), and update the list of contributors and any changes to transitional notes from the x.y branch.&lt;br /&gt;
** In src/patchlevel.h, update KRB5_MINOR_RELEASE to y+1.&lt;br /&gt;
** Commit with the message &amp;quot;Updates for krb5-x.(y+1)-prerelease&amp;quot; and push to the authoritative repository.&lt;br /&gt;
* Update web pages&lt;br /&gt;
** Create directory /mit/kerberos/dist/krb5/x.y and copy HEADER from a previous directory&lt;br /&gt;
** Create directories /mit/kerberos/krb5-x.y and /mit/kerberos/krb5-x.y/RCS&lt;br /&gt;
&lt;br /&gt;
==Preparing releases==&lt;br /&gt;
&lt;br /&gt;
===Pre-mkrel===&lt;br /&gt;
&lt;br /&gt;
* check copyright years in project-wide stuff&lt;br /&gt;
* make sure you're in a build tree that's not the source tree and configured using &amp;lt;code&amp;gt;--enable-maintainer-mode&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;make regen&amp;lt;/code&amp;gt; and commit if there is more than just a pot file date change, with the commit message &amp;quot;make regen&amp;quot;&lt;br /&gt;
* manually edit patchlevel.h to reflect the new release&lt;br /&gt;
** for a patch release, increment KRB5_PATCHLEVEL, change the next line to &amp;quot;/* #undef KRB5_RELTAIL */&amp;quot;, and change KRB5_RELTAG to &amp;quot;krb5-x.y.z-final&amp;quot;&lt;br /&gt;
** for an alpha or beta release, set KRB5_RELTAIL to &amp;quot;beta1&amp;quot; or similar, and change KRB5_RELTAG to &amp;quot;krb5-x.y-beta1&amp;quot; or similar.&lt;br /&gt;
* manually update README&lt;br /&gt;
** release dates (in major changes heading, ISO 8601 date format with hyphens)&lt;br /&gt;
*** we do not have release dates for alpha or beta releases; add one when making the first final x.y release&lt;br /&gt;
** changes&lt;br /&gt;
*** note whether bugfix release, maintenance vs current release&lt;br /&gt;
*** bullet list of major changes&lt;br /&gt;
*** minor changes = list of RT tickets fixed -- always grab a fresh list from RT when editing these!  (https://krbdev.mit.edu/rt/NoAuth/krb5-x.y/fixed-x.y.z.html)&lt;br /&gt;
** contributors (RT is a good source for these; click through the ticket links from the above URL and look for reporter and patch author names)&lt;br /&gt;
** double-check dates and release numbers in new section headings&lt;br /&gt;
* re-run &amp;lt;code&amp;gt;make regen&amp;lt;/code&amp;gt; with updated patchlevel.h&lt;br /&gt;
* commit the README, patchlevel-specific man page, and template changes with the subject &amp;quot;Update for krb5-x.y.z&amp;quot;&lt;br /&gt;
* &amp;lt;code&amp;gt;git tag krb5-x.y.z-final&amp;lt;/code&amp;gt; (or &amp;lt;code&amp;gt;krb5-x.y-beta1&amp;lt;/code&amp;gt; or similar for an alpha or beta release)&lt;br /&gt;
&lt;br /&gt;
===Running mkrel===&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;path_to_mkrel/mkrel --repository $YOUR_SOURCE_TREE krb5-x.y.z-final krb5-x.y.z&amp;lt;/code&amp;gt;&lt;br /&gt;
** For an alpha or beta release, &amp;lt;code&amp;gt;path_to_mkrel/mkrel --repository $YOUR_SOURCE_TREE krb5-x.y-beta1 krb5-x.y-beta1&amp;lt;/code&amp;gt; or similar&lt;br /&gt;
* manually inspect output for versioning and correctness&lt;br /&gt;
** HTML docs&lt;br /&gt;
** PDF docs&lt;br /&gt;
** patchlevel.h as modified by mkrel&lt;br /&gt;
* push release branch commits and release tags to authoritative repository&lt;br /&gt;
** you will need to be in hooks.branchers in the authoritative repository to push the tags&lt;br /&gt;
&lt;br /&gt;
===Post-mkrel===&lt;br /&gt;
&lt;br /&gt;
* PGP sign (&amp;lt;code&amp;gt;gpg -ab krb5-x.y.z.tar.gz&amp;lt;/code&amp;gt;, generates krb5-x.y.z.tar.gz.asc)&lt;br /&gt;
* copy tar file and signature into /mit/kerberos/dist/krb5/x.y&lt;br /&gt;
* for alpha and beta releases:&lt;br /&gt;
** create /mit/kerberos/krb5-x.y/krb5-x.y.html based on the first commit from a previous release&lt;br /&gt;
** symlink index.html to krb5-x.y.html in that directory&lt;br /&gt;
** place an entry in /mit/kerberos/dist/testing.html&lt;br /&gt;
** send an announcement to krbdev@mit.edu&lt;br /&gt;
** edit src/patchlevel.h, changing KRB5_RELTAIL to &amp;quot;beta1-postrelease&amp;quot; (or similar) and KRB5_RELTAG to &amp;quot;krb5-x.y&amp;quot;.  Commit with the subject &amp;quot;Update for krb5-x.y-beta1-postrelease&amp;quot; or similar and push to the authoritative repository.&lt;br /&gt;
** skip all remaining steps&lt;br /&gt;
* create /mit/kerberos/krb5-x.y/krb5-x.y.z and /mit/kerberos/krb5-x.y/krb5-x.y.z/doc&lt;br /&gt;
* copy signature to /mit/kerberos/krb5-x.y/krb5-x.y.z.sig&lt;br /&gt;
* copy README from release source code to /mit/kerberos/krb5-x.y/README-x.y.z.txt&lt;br /&gt;
* generate branded HTML docs&lt;br /&gt;
** &amp;lt;code&amp;gt;HTML_LOGO=/mit/kerberos/mitkc-logo-sm.png make html&amp;lt;/code&amp;gt;&lt;br /&gt;
** we don't ship the branded (with logo) docs because the logo is an MIT trademark&lt;br /&gt;
** copy the resulting documentation tree to /mit/kerberos/krb5-x.y/krb5-x.y.z/doc/html&lt;br /&gt;
** repeat for &amp;lt;code&amp;gt;HTML_LOGO=... make pdf&amp;lt;/code&amp;gt; and .../doc/pdf&lt;br /&gt;
* update RT configuration&lt;br /&gt;
** check that https://krbdev.mit.edu/rt/NoAuth/krb5-x.y/fixed-x.y.z.html and .../bugs-x.y.z.html work&lt;br /&gt;
** in the web interface, to go Admin -&amp;gt; Custom Fields -&amp;gt; Version_Fixed and add a new one for the next patch release&lt;br /&gt;
* edit web pages&lt;br /&gt;
** create /mit/kerberos/krb5-x.y/krb5-x.y.z.html and check it into RCS, using similar files as an example (for the first x.y release, update krb5-x.y.html using the previous release's krb5-x.y.html as an example)&lt;br /&gt;
** update /mit/kerberos/index.html with the new release numbers (possibly removing out-of-service releases) and add entries to the &amp;quot;Recent news&amp;quot; section; add old release entries to historical.html and old news items to oldnews.html&lt;br /&gt;
** update /mit/kerberos/dist/index.html with new release references (possibly removing out-of-service releases); add old entries to historic.html&lt;br /&gt;
** review edited web pages in a web browser and double check that release numbers and release dates have been updated&lt;br /&gt;
** update /mit/kerberos/krb5-x.y/doc and /mit/kerberos/krb5-x.y/index.html symlinks&lt;br /&gt;
** update /mit/kerberos/krb5-latest symlink if this is a major or minor release&lt;br /&gt;
** for the first final krb5-x.y release, remove the entry from /mit/kerberos/dist/testing.html&lt;br /&gt;
* send announcement to kerberos-announce&lt;br /&gt;
* make followup versioning commit to release branch&lt;br /&gt;
** edit src/patchlevel.h, setting KRB5_RELTAIL to &amp;quot;postrelease&amp;quot; and KRB5_RELTAG to &amp;quot;krb5-x.y&amp;quot;&lt;br /&gt;
** use the commit message &amp;quot;Update for krb5-x.y.z-postrelease&amp;quot;&lt;br /&gt;
** push this commit to the authoritative repository&lt;/div&gt;</summary>
		<author><name>Ghudson</name></author>	</entry>

	<entry>
		<id>https://k5wiki.kerberos.org/wiki?title=Release_engineering_notes&amp;diff=6037</id>
		<title>Release engineering notes</title>
		<link rel="alternate" type="text/html" href="https://k5wiki.kerberos.org/wiki?title=Release_engineering_notes&amp;diff=6037"/>
				<updated>2023-04-17T14:26:29Z</updated>
		
		<summary type="html">&lt;p&gt;Ghudson: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Release engineering environment==&lt;br /&gt;
&lt;br /&gt;
Release engineering operations are currently performed on a Ubuntu 18.04 host.  Updates to the Ubuntu version may cause churn in the generated files which are checked into the repository due to newer versions of programs in the toolchain.&lt;br /&gt;
&lt;br /&gt;
The release engineering host must have the following packages installed:&lt;br /&gt;
&lt;br /&gt;
* autoconf&lt;br /&gt;
* bison&lt;br /&gt;
* build-essential&lt;br /&gt;
* dejagnu&lt;br /&gt;
* doxygen&lt;br /&gt;
* flex&lt;br /&gt;
* git&lt;br /&gt;
* keyutils&lt;br /&gt;
* ldap-utils&lt;br /&gt;
* libcmocka-dev&lt;br /&gt;
* libkeyutils-dev&lt;br /&gt;
* libldap2-dev&lt;br /&gt;
* liblmdb-dev&lt;br /&gt;
* libresolv-wrapper&lt;br /&gt;
* libsasl2-dev&lt;br /&gt;
* libssl-dev&lt;br /&gt;
* libtool&lt;br /&gt;
* pkg-config&lt;br /&gt;
* python-sphinx&lt;br /&gt;
* python-cheetah&lt;br /&gt;
* rcs&lt;br /&gt;
* slapd&lt;br /&gt;
* tcl-dev&lt;br /&gt;
* texlive&lt;br /&gt;
* texlive-latex-extra&lt;br /&gt;
&lt;br /&gt;
==Pulling up changes to release branches==&lt;br /&gt;
&lt;br /&gt;
* For each supported release (usually the most recent and one previous release), prepare a git working copy with the krb5-x.y branch checked out from the authoritative repository.  From the krbdev-services repository, copy githooks/hookutils.py and githooks-client/prepare-commit-msg into .git/hooks for both working copies.&lt;br /&gt;
&lt;br /&gt;
* Check that each working copy is clean, has no unexpected extra commits, and is up to date with the authoritative repository.  Checking the output of &amp;quot;git status&amp;quot; and running &amp;quot;git pull&amp;quot; should accomplish this.&lt;br /&gt;
&lt;br /&gt;
* At https://krbdev.mit.edu:444/rt/ , start a new search, add the term &amp;quot;queue is krb5&amp;quot;, then the criteria &amp;quot;tags is pullup&amp;quot;, then search.  It can be useful to create a browser tab for each search result.&lt;br /&gt;
&lt;br /&gt;
* If there has been a calendar year change since the last patch release, pull up the commit(s) which bump the project-wide copyright years as well.&lt;br /&gt;
&lt;br /&gt;
* For each release branch:&lt;br /&gt;
** For each ticket marked for pullup to that branch:&lt;br /&gt;
*** For each commit listed in the ticket, run &amp;quot;KRB5_VERSION_FIXED=x.y.z git cherry-pick -x COMMIT&amp;quot;, and address any merge conflicts.  x.y.z should be the next patch release that will be created on the release branch.  If there are merge conflicts, &amp;quot;git cherry-pick --continue&amp;quot; will not apply the log message hook, so edit the RT fields manually.&lt;br /&gt;
*** Examine the commits any consider any possible interactions with changes made since the release branch.&lt;br /&gt;
*** Run &amp;quot;make&amp;quot; and &amp;quot;make check&amp;quot;.  Remember that &amp;quot;make check&amp;quot; will not work for multiple working directories concurrently on the same host.&lt;br /&gt;
*** If the change isn't covered by automated tests, consider testing it by hand.&lt;br /&gt;
* Consider pushing the updated release branches to a personal github fork integrated with Travis, and waiting for Travis to finish building and testing it.&lt;br /&gt;
* If the pulled up changes are substantial, consider running a build and check of each release branch on krbdev-sparc-build.&lt;br /&gt;
* Push the updated release branches to the authoritative repository.&lt;br /&gt;
* Remove the &amp;quot;pullup&amp;quot; tag from each ticket.  This can be done in a bulk update from the search result page, or it can be done on each ticket individually from the jumbo page.&lt;br /&gt;
&lt;br /&gt;
==Creating a new release branch==&lt;br /&gt;
&lt;br /&gt;
* At https://krbdev.mit.edu:444/rt/ , go to Admin -&amp;gt; Custom Fields -&amp;gt; Target_version and add x.y and x.y-next values.  Do the same for Version_Fixed.&lt;br /&gt;
* At https://krbdev.mit.edu:444/rt/ , perform a search with the following criteria:&lt;br /&gt;
** Queue is krb5&lt;br /&gt;
** Status is resolved&lt;br /&gt;
** Version_Fixed is (no value)&lt;br /&gt;
** Tags is not unsupported&lt;br /&gt;
** Tags is not noresource&lt;br /&gt;
** Tags is not nochange&lt;br /&gt;
* Verify that the resulting list of tickets are all for changes introduced in the past development cycle, and bulk update them to have Version_Fixed x.y.&lt;br /&gt;
* On the master branch, update doc/mitK5features.rst, updating the &amp;quot;Latest stable&amp;quot; and &amp;quot;Supported&amp;quot; release numbers.  Write up a list of major changes for the new release, broken down by category.  Code quality changes usually do not have associated tickets, so review the version history for commits with no RT headers.  Commit with the subject &amp;quot;Update features list for x.y&amp;quot;.&lt;br /&gt;
* On the master branch, update &amp;lt;code&amp;gt;config.guess&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;config.sub&amp;lt;/code&amp;gt; from &amp;lt;code&amp;gt;git://git.savannah.gnu.org/config.git&amp;lt;/code&amp;gt;.  Commit with the subject &amp;quot;Update config.guess, config.sub&amp;quot;&lt;br /&gt;
* On the master branch, run &amp;quot;make regen&amp;quot;.  Commit with the subject &amp;quot;make regen&amp;quot;.  Push the master branch to the authoritative repository.&lt;br /&gt;
* Create the new branch and push it to the authoritative repository.&lt;br /&gt;
* On the new branch, update README for the new release:&lt;br /&gt;
** Make sure that all x.y references are for the new version (they should be already).&lt;br /&gt;
** Update any notes about transitions (such as enctype deprecations) and add new ones if necessary.&lt;br /&gt;
** Include the list of major changes for the new release.&lt;br /&gt;
** Include the list of tickets changed (copy-paste from https://krbdev.mit.edu/rt/NoAuth/krb5-x.y/fixed-x.y.z.html).&lt;br /&gt;
** Copy the list of contributors from the previous release branch.&lt;br /&gt;
** Add contributors from the RT tickets for the new release branch.&lt;br /&gt;
** Commit with the message &amp;quot;Update README for krb5-x.y&amp;quot; and push to the authoritative repository.&lt;br /&gt;
* On the master branch, update README for the next prerelease:&lt;br /&gt;
** In README, update x.y references to x.(y+1), and update the list of contributors and any changes to transitional notes from the x.y branch.&lt;br /&gt;
** In src/patchlevel.h, update KRB5_MINOR_RELEASE to y+1.&lt;br /&gt;
** Commit with the message &amp;quot;Updates for krb5-x.(y+1)-prerelease&amp;quot; and push to the authoritative repository.&lt;br /&gt;
* Update web pages&lt;br /&gt;
** Create directory /mit/kerberos/dist/krb5/x.y and copy HEADER from a previous directory&lt;br /&gt;
** Create directories /mit/kerberos/krb5-x.y and /mit/kerberos/krb5-x.y/RCS&lt;br /&gt;
&lt;br /&gt;
==Preparing releases==&lt;br /&gt;
&lt;br /&gt;
===Pre-mkrel===&lt;br /&gt;
&lt;br /&gt;
* check copyright years in project-wide stuff&lt;br /&gt;
* make sure you're in a build tree that's not the source tree and configured using &amp;lt;code&amp;gt;--enable-maintainer-mode&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;make regen&amp;lt;/code&amp;gt; and commit if there is more than just a pot file date change, with the commit message &amp;quot;make regen&amp;quot;&lt;br /&gt;
* manually edit patchlevel.h to reflect the new release&lt;br /&gt;
** for a patch release, increment KRB5_PATCHLEVEL, change the next line to &amp;quot;/* #undef KRB5_RELTAIL */&amp;quot;, and change KRB5_RELTAG to &amp;quot;krb5-x.y.z-final&amp;quot;&lt;br /&gt;
** for an alpha or beta release, set KRB5_RELTAIL to &amp;quot;beta1&amp;quot; or similar, and change KRB5_RELTAG to &amp;quot;krb5-x.y-beta1&amp;quot; or similar.&lt;br /&gt;
* manually update README&lt;br /&gt;
** release dates (in major changes heading, ISO 8601 date format with hyphens)&lt;br /&gt;
*** we do not have release dates for alpha or beta releases; add one when making the first final x.y release&lt;br /&gt;
** changes&lt;br /&gt;
*** note whether bugfix release, maintenance vs current release&lt;br /&gt;
*** bullet list of major changes&lt;br /&gt;
*** minor changes = list of RT tickets fixed -- always grab a fresh list from RT when editing these!  (https://krbdev.mit.edu/rt/NoAuth/krb5-x.y/fixed-x.y.z.html)&lt;br /&gt;
** contributors (RT is a good source for these; click through the ticket links from the above URL and look for reporter and patch author names)&lt;br /&gt;
** double-check dates and release numbers in new section headings&lt;br /&gt;
* re-run &amp;lt;code&amp;gt;make regen&amp;lt;/code&amp;gt; with updated patchlevel.h&lt;br /&gt;
* commit the README, patchlevel-specific man page, and template changes with the subject &amp;quot;Update for krb5-x.y.z&amp;quot;&lt;br /&gt;
* &amp;lt;code&amp;gt;git tag krb5-x.y.z-final&amp;lt;/code&amp;gt; (or &amp;lt;code&amp;gt;krb5-x.y-beta1&amp;lt;/code&amp;gt; or similar for an alpha or beta release)&lt;br /&gt;
&lt;br /&gt;
===Running mkrel===&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;path_to_mkrel/mkrel --repository $YOUR_SOURCE_TREE krb5-x.y.z-final krb5-x.y.z&amp;lt;/code&amp;gt;&lt;br /&gt;
** For an alpha or beta release, &amp;lt;code&amp;gt;path_to_mkrel/mkrel --repository $YOUR_SOURCE_TREE krb5-x.y-beta1 krb5-x.y-beta1&amp;lt;/code&amp;gt; or similar&lt;br /&gt;
* manually inspect output for versioning and correctness&lt;br /&gt;
** HTML docs&lt;br /&gt;
** PDF docs&lt;br /&gt;
** patchlevel.h as modified by mkrel&lt;br /&gt;
* push release branch commits and release tags to authoritative repository&lt;br /&gt;
** you will need to be in hooks.branchers in the authoritative repository to push the tags&lt;br /&gt;
&lt;br /&gt;
===Post-mkrel===&lt;br /&gt;
&lt;br /&gt;
* PGP sign (&amp;lt;code&amp;gt;gpg -ab krb5-x.y.z.tar.gz&amp;lt;/code&amp;gt;, generates krb5-x.y.z.tar.gz.asc)&lt;br /&gt;
* copy tar file and signature into /mit/kerberos/dist/krb5/x.y&lt;br /&gt;
* for alpha and beta releases:&lt;br /&gt;
** create /mit/kerberos/krb5-x.y/krb5-x.y.html based on the first commit from a previous release&lt;br /&gt;
** symlink index.html to krb5-x.y.html in that directory&lt;br /&gt;
** place an entry in /mit/kerberos/dist/testing.html&lt;br /&gt;
** send an announcement to krbdev@mit.edu&lt;br /&gt;
** edit src/patchlevel.h, changing KRB5_RELTAIL to &amp;quot;beta1-postrelease&amp;quot; (or similar) and KRB5_RELTAG to &amp;quot;krb5-x.y&amp;quot;.  Commit with the subject &amp;quot;Update for krb5-x.y-beta1-postrelease&amp;quot; or similar and push to the authoritative repository.&lt;br /&gt;
** skip all remaining steps&lt;br /&gt;
* create /mit/kerberos/krb5-x.y/krb5-x.y.z and /mit/kerberos/krb5-x.y/krb5-x.y.z/doc&lt;br /&gt;
* copy signature to /mit/kerberos/krb5-x.y/krb5-x.y.z.sig&lt;br /&gt;
* copy README from release source code to /mit/kerberos/krb5-x.y/README-x.y.z.txt&lt;br /&gt;
* generate branded HTML docs&lt;br /&gt;
** &amp;lt;code&amp;gt;HTML_LOGO=/mit/kerberos/mitkc-logo-sm.png make html&amp;lt;/code&amp;gt;&lt;br /&gt;
** we don't ship the branded (with logo) docs because the logo is an MIT trademark&lt;br /&gt;
** copy the resulting documentation tree to /mit/kerberos/krb5-x.y/krb5-x.y.z/doc/html&lt;br /&gt;
** repeat for &amp;lt;code&amp;gt;HTML_LOGO=... make pdf&amp;lt;/code&amp;gt; and .../doc/pdf&lt;br /&gt;
* update RT configuration&lt;br /&gt;
** check that https://krbdev.mit.edu/rt/NoAuth/krb5-x.y/fixed-x.y.z.html and .../bugs-x.y.z.html work&lt;br /&gt;
** in the web interface, to go Admin -&amp;gt; Custom Fields -&amp;gt; Version_Fixed and add a new one for the next patch release&lt;br /&gt;
* edit web pages&lt;br /&gt;
** create /mit/kerberos/krb5-x.y/krb5-x.y.z.html and check it into RCS, using similar files as an example (for the first x.y release, update krb5-x.y.html using the previous release's krb5-x.y.html as an example)&lt;br /&gt;
** update /mit/kerberos/index.html with the new release numbers (possibly removing out-of-service releases) and add entries to the &amp;quot;Recent news&amp;quot; section; add old release entries to historical.html and old news items to oldnews.html&lt;br /&gt;
** update /mit/kerberos/dist/index.html with new release references (possibly removing out-of-service releases); add old entries to historic.html&lt;br /&gt;
** review edited web pages in a web browser and double check that release numbers and release dates have been updated&lt;br /&gt;
** update /mit/kerberos/krb5-x.y/doc and /mit/kerberos/krb5-x.y/index.html symlinks&lt;br /&gt;
** update /mit/kerberos/krb5-latest symlink if this is a major or minor release&lt;br /&gt;
** for the first final krb5-x.y release, remove the entry from /mit/kerberos/dist/testing.html&lt;br /&gt;
* send announcement to kerberos-announce&lt;br /&gt;
* make followup versioning commit to release branch&lt;br /&gt;
** edit src/patchlevel.h, setting KRB5_RELTAIL to &amp;quot;postrelease&amp;quot; and KRB5_RELTAG to &amp;quot;krb5-x.y&amp;quot;&lt;br /&gt;
** use the commit message &amp;quot;Update for krb5-x.y.z-postrelease&amp;quot;&lt;br /&gt;
** push this commit to the authoritative repository&lt;/div&gt;</summary>
		<author><name>Ghudson</name></author>	</entry>

	<entry>
		<id>https://k5wiki.kerberos.org/wiki?title=Release_engineering_notes&amp;diff=6036</id>
		<title>Release engineering notes</title>
		<link rel="alternate" type="text/html" href="https://k5wiki.kerberos.org/wiki?title=Release_engineering_notes&amp;diff=6036"/>
				<updated>2023-04-13T22:48:26Z</updated>
		
		<summary type="html">&lt;p&gt;Ghudson: /* Creating a new release branch */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Release engineering environment==&lt;br /&gt;
&lt;br /&gt;
Release engineering operations are currently performed on a Ubuntu 18.04 host.  Updates to the Ubuntu version may cause churn in the generated files which are checked into the repository due to newer versions of programs in the toolchain.&lt;br /&gt;
&lt;br /&gt;
The release engineering host must have the following packages installed:&lt;br /&gt;
&lt;br /&gt;
* autoconf&lt;br /&gt;
* bison&lt;br /&gt;
* build-essential&lt;br /&gt;
* dejagnu&lt;br /&gt;
* doxygen&lt;br /&gt;
* flex&lt;br /&gt;
* git&lt;br /&gt;
* keyutils&lt;br /&gt;
* ldap-utils&lt;br /&gt;
* libcmocka-dev&lt;br /&gt;
* libkeyutils-dev&lt;br /&gt;
* libldap2-dev&lt;br /&gt;
* liblmdb-dev&lt;br /&gt;
* libresolv-wrapper&lt;br /&gt;
* libsasl2-dev&lt;br /&gt;
* libssl-dev&lt;br /&gt;
* libtool&lt;br /&gt;
* pkg-config&lt;br /&gt;
* python-sphinx&lt;br /&gt;
* python-cheetah&lt;br /&gt;
* rcs&lt;br /&gt;
* slapd&lt;br /&gt;
* tcl-dev&lt;br /&gt;
* texlive&lt;br /&gt;
* texlive-latex-extra&lt;br /&gt;
&lt;br /&gt;
==Pulling up changes to release branches==&lt;br /&gt;
&lt;br /&gt;
* For each supported release (usually the most recent and one previous release), prepare a git working copy with the krb5-x.y branch checked out from the authoritative repository.  From the krbdev-services repository, copy githooks/hookutils.py and githooks-client/prepare-commit-msg into .git/hooks for both working copies.&lt;br /&gt;
&lt;br /&gt;
* Check that each working copy is clean, has no unexpected extra commits, and is up to date with the authoritative repository.  Checking the output of &amp;quot;git status&amp;quot; and running &amp;quot;git pull&amp;quot; should accomplish this.&lt;br /&gt;
&lt;br /&gt;
* At https://krbdev.mit.edu:444/rt/ , start a new search, add the term &amp;quot;queue is krb5&amp;quot;, then the criteria &amp;quot;tags is pullup&amp;quot;, then search.  It can be useful to create a browser tab for each search result.&lt;br /&gt;
&lt;br /&gt;
* If there has been a calendar year change since the last patch release, pull up the commit(s) which bump the project-wide copyright years as well.&lt;br /&gt;
&lt;br /&gt;
* For each release branch:&lt;br /&gt;
** For each ticket marked for pullup to that branch:&lt;br /&gt;
*** For each commit listed in the ticket, run &amp;quot;KRB5_VERSION_FIXED=x.y.z git cherry-pick -x COMMIT&amp;quot;, and address any merge conflicts.  x.y.z should be the next patch release that will be created on the release branch.  If there are merge conflicts, &amp;quot;git cherry-pick --continue&amp;quot; will not apply the log message hook, so edit the RT fields manually.&lt;br /&gt;
*** Examine the commits any consider any possible interactions with changes made since the release branch.&lt;br /&gt;
*** Run &amp;quot;make&amp;quot; and &amp;quot;make check&amp;quot;.  Remember that &amp;quot;make check&amp;quot; will not work for multiple working directories concurrently on the same host.&lt;br /&gt;
*** If the change isn't covered by automated tests, consider testing it by hand.&lt;br /&gt;
* Consider pushing the updated release branches to a personal github fork integrated with Travis, and waiting for Travis to finish building and testing it.&lt;br /&gt;
* If the pulled up changes are substantial, consider running a build and check of each release branch on krbdev-sparc-build.&lt;br /&gt;
* Push the updated release branches to the authoritative repository.&lt;br /&gt;
* Remove the &amp;quot;pullup&amp;quot; tag from each ticket.  This can be done in a bulk update from the search result page, or it can be done on each ticket individually from the jumbo page.&lt;br /&gt;
&lt;br /&gt;
==Creating a new release branch==&lt;br /&gt;
&lt;br /&gt;
* At https://krbdev.mit.edu:444/rt/ , go to Admin -&amp;gt; Custom Fields -&amp;gt; Target_version and add x.y and x.y-next values.  Do the same for Version_Fixed.&lt;br /&gt;
* At https://krbdev.mit.edu:444/rt/ , perform a search with the following criteria:&lt;br /&gt;
** Queue is krb5&lt;br /&gt;
** Status is resolved&lt;br /&gt;
** Version_Fixed is (no value)&lt;br /&gt;
** Tags is not unsupported&lt;br /&gt;
** Tags is not noresource&lt;br /&gt;
** Tags is not nochange&lt;br /&gt;
* Verify that the resulting list of tickets are all for changes introduced in the past development cycle, and bulk update them to have Version_Fixed x.y.&lt;br /&gt;
* On the master branch, update doc/mitK5features.rst, updating the &amp;quot;Latest stable&amp;quot; and &amp;quot;Supported&amp;quot; release numbers.  Write up a list of major changes for the new release, broken down by category.  Code quality changes usually do not have associated tickets, so review the version history for commits with no RT headers.  Commit with the subject &amp;quot;Update features list for x.y&amp;quot;.&lt;br /&gt;
* On the master branch, update &amp;lt;code&amp;gt;config.guess&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;config.sub&amp;lt;/code&amp;gt; from &amp;lt;code&amp;gt;git://git.savannah.gnu.org/config.git&amp;lt;/code&amp;gt;.  Commit with the subject &amp;quot;Update config.guess, config.sub&amp;quot;&lt;br /&gt;
* On the master branch, run &amp;quot;make regen&amp;quot;.  Commit with the subject &amp;quot;make regen&amp;quot;.  Push the master branch to the authoritative repository.&lt;br /&gt;
* Create the new branch and push it to the authoritative repository.&lt;br /&gt;
* On the new branch, update README for the new release:&lt;br /&gt;
** Make sure that all x.y references are for the new version (they should be already).&lt;br /&gt;
** Update any notes about transitions (such as enctype deprecations) and add new ones if necessary.&lt;br /&gt;
** Include the list of major changes for the new release.&lt;br /&gt;
** Include the list of tickets changed (copy-paste from https://krbdev.mit.edu/rt/NoAuth/krb5-x.y/fixed-x.y.z.html).&lt;br /&gt;
** Copy the list of contributors from the previous release branch.&lt;br /&gt;
** Add contributors from the RT tickets for the new release branch.&lt;br /&gt;
** Commit with the message &amp;quot;Update README for krb5-x.y&amp;quot; and push to the authoritative repository.&lt;br /&gt;
* On the master branch, update README for the next prerelease:&lt;br /&gt;
** In README, update x.y references to x.(y+1), and update the list of contributors and any changes to transitional notes from the x.y branch.&lt;br /&gt;
** In src/patchlevel.h, update KRB5_MINOR_RELEASE to y+1.&lt;br /&gt;
** Commit with the message &amp;quot;Updates for krb5-x.(y+1)-prerelease&amp;quot; and push to the authoritative repository.&lt;br /&gt;
* Update web pages&lt;br /&gt;
** Create directory /mit/kerberos/dist/krb5/x.y and copy HEADER from a previous directory&lt;br /&gt;
** Create directories /mit/kerberos/krb5-x.y and /mit/kerberos/krb5-x.y/RCS&lt;br /&gt;
&lt;br /&gt;
==Preparing releases==&lt;br /&gt;
&lt;br /&gt;
===Pre-mkrel===&lt;br /&gt;
&lt;br /&gt;
* check copyright years in project-wide stuff&lt;br /&gt;
* make sure you're in a build tree that's not the source tree and configured using &amp;lt;code&amp;gt;--enable-maintainer-mode&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;make depend&amp;lt;/code&amp;gt; and commit if changed, with the commit message &amp;quot;make depend&amp;quot;&lt;br /&gt;
* regenerate manpages: &amp;lt;code&amp;gt;(cd man &amp;amp;&amp;amp; make man)&amp;lt;/code&amp;gt; and commit if changed, with the commit message &amp;quot;Update man pages&amp;quot;&lt;br /&gt;
* regenerate localization template &amp;lt;code&amp;gt;(cd po &amp;amp;&amp;amp; make update-po)&amp;lt;/code&amp;gt; and commit if changed, with the commit message &amp;quot;make update-po&amp;quot;&lt;br /&gt;
* manually edit patchlevel.h to reflect the new release&lt;br /&gt;
** for a patch release, increment KRB5_PATCHLEVEL, change the next line to &amp;quot;/* #undef KRB5_RELTAIL */&amp;quot;, and change KRB5_RELTAG to &amp;quot;krb5-x.y.z-final&amp;quot;&lt;br /&gt;
** for an alpha or beta release, set KRB5_RELTAIL to &amp;quot;beta1&amp;quot; or similar, and change KRB5_RELTAG to &amp;quot;krb5-x.y-beta1&amp;quot; or similar.&lt;br /&gt;
* manually update README&lt;br /&gt;
** release dates (in major changes heading, ISO 8601 date format with hyphens)&lt;br /&gt;
*** we do not have release dates for alpha or beta releases; add one when making the first final x.y release&lt;br /&gt;
** changes&lt;br /&gt;
*** note whether bugfix release, maintenance vs current release&lt;br /&gt;
*** bullet list of major changes&lt;br /&gt;
*** minor changes = list of RT tickets fixed -- always grab a fresh list from RT when editing these!  (https://krbdev.mit.edu/rt/NoAuth/krb5-x.y/fixed-x.y.z.html)&lt;br /&gt;
** contributors (RT is a good source for these; click through the ticket links from the above URL and look for reporter and patch author names)&lt;br /&gt;
** double-check dates and release numbers in new section headings&lt;br /&gt;
* re-run &amp;lt;code&amp;gt;(cd man &amp;amp;&amp;amp; make man)&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;(cd po &amp;amp;&amp;amp; make update-po)&amp;lt;/code&amp;gt; with updated patchlevel.h&lt;br /&gt;
** If there is no update to Project-Id-Version in mit-krb5.pot, touch configure.in and re-run make, then run &amp;lt;code&amp;gt;(cd po &amp;amp;&amp;amp; make update-po)&amp;lt;/code&amp;gt; again.  (This should no longer be necessary after {{bug|8560}}.)&lt;br /&gt;
* commit the README, patchlevel-specific man page, and template changes with the subject &amp;quot;Update for krb5-x.y.z&amp;quot;&lt;br /&gt;
* &amp;lt;code&amp;gt;git tag krb5-x.y.z-final&amp;lt;/code&amp;gt; (or &amp;lt;code&amp;gt;krb5-x.y-beta1&amp;lt;/code&amp;gt; or similar for an alpha or beta release)&lt;br /&gt;
&lt;br /&gt;
===Running mkrel===&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;path_to_mkrel/mkrel --repository $YOUR_SOURCE_TREE krb5-x.y.z-final krb5-x.y.z&amp;lt;/code&amp;gt;&lt;br /&gt;
** For an alpha or beta release, &amp;lt;code&amp;gt;path_to_mkrel/mkrel --repository $YOUR_SOURCE_TREE krb5-x.y-beta1 krb5-x.y-beta1&amp;lt;/code&amp;gt; or similar&lt;br /&gt;
* manually inspect output for versioning and correctness&lt;br /&gt;
** HTML docs&lt;br /&gt;
** PDF docs&lt;br /&gt;
** patchlevel.h as modified by mkrel&lt;br /&gt;
* push release branch commits and release tags to authoritative repository&lt;br /&gt;
** you will need to be in hooks.branchers in the authoritative repository to push the tags&lt;br /&gt;
&lt;br /&gt;
===Post-mkrel===&lt;br /&gt;
&lt;br /&gt;
* PGP sign (&amp;lt;code&amp;gt;gpg -ab krb5-x.y.z.tar.gz&amp;lt;/code&amp;gt;, generates krb5-x.y.z.tar.gz.asc)&lt;br /&gt;
* copy tar file and signature into /mit/kerberos/dist/krb5/x.y&lt;br /&gt;
* for alpha and beta releases:&lt;br /&gt;
** create /mit/kerberos/krb5-x.y/krb5-x.y.html based on the first commit from a previous release&lt;br /&gt;
** symlink index.html to krb5-x.y.html in that directory&lt;br /&gt;
** place an entry in /mit/kerberos/dist/testing.html&lt;br /&gt;
** send an announcement to krbdev@mit.edu&lt;br /&gt;
** edit src/patchlevel.h, changing KRB5_RELTAIL to &amp;quot;beta1-postrelease&amp;quot; (or similar) and KRB5_RELTAG to &amp;quot;krb5-x.y&amp;quot;.  Commit with the subject &amp;quot;Update for krb5-x.y-beta1-postrelease&amp;quot; or similar and push to the authoritative repository.&lt;br /&gt;
** skip all remaining steps&lt;br /&gt;
* create /mit/kerberos/krb5-x.y/krb5-x.y.z and /mit/kerberos/krb5-x.y/krb5-x.y.z/doc&lt;br /&gt;
* copy signature to /mit/kerberos/krb5-x.y/krb5-x.y.z.sig&lt;br /&gt;
* copy README from release source code to /mit/kerberos/krb5-x.y/README-x.y.z.txt&lt;br /&gt;
* generate branded HTML docs&lt;br /&gt;
** &amp;lt;code&amp;gt;HTML_LOGO=/mit/kerberos/mitkc-logo-sm.png make html&amp;lt;/code&amp;gt;&lt;br /&gt;
** we don't ship the branded (with logo) docs because the logo is an MIT trademark&lt;br /&gt;
** copy the resulting documentation tree to /mit/kerberos/krb5-x.y/krb5-x.y.z/doc/html&lt;br /&gt;
** repeat for &amp;lt;code&amp;gt;HTML_LOGO=... make pdf&amp;lt;/code&amp;gt; and .../doc/pdf&lt;br /&gt;
* update RT configuration&lt;br /&gt;
** check that https://krbdev.mit.edu/rt/NoAuth/krb5-x.y/fixed-x.y.z.html and .../bugs-x.y.z.html work&lt;br /&gt;
** in the web interface, to go Admin -&amp;gt; Custom Fields -&amp;gt; Version_Fixed and add a new one for the next patch release&lt;br /&gt;
* edit web pages&lt;br /&gt;
** create /mit/kerberos/krb5-x.y/krb5-x.y.z.html and check it into RCS, using similar files as an example (for the first x.y release, update krb5-x.y.html using the previous release's krb5-x.y.html as an example)&lt;br /&gt;
** update /mit/kerberos/index.html with the new release numbers (possibly removing out-of-service releases) and add entries to the &amp;quot;Recent news&amp;quot; section; add old release entries to historical.html and old news items to oldnews.html&lt;br /&gt;
** update /mit/kerberos/dist/index.html with new release references (possibly removing out-of-service releases); add old entries to historic.html&lt;br /&gt;
** review edited web pages in a web browser and double check that release numbers and release dates have been updated&lt;br /&gt;
** update /mit/kerberos/krb5-x.y/doc and /mit/kerberos/krb5-x.y/index.html symlinks&lt;br /&gt;
** update /mit/kerberos/krb5-latest symlink if this is a major or minor release&lt;br /&gt;
** for the first final krb5-x.y release, remove the entry from /mit/kerberos/dist/testing.html&lt;br /&gt;
* send announcement to kerberos-announce&lt;br /&gt;
* make followup versioning commit to release branch&lt;br /&gt;
** edit src/patchlevel.h, setting KRB5_RELTAIL to &amp;quot;postrelease&amp;quot; and KRB5_RELTAG to &amp;quot;krb5-x.y&amp;quot;&lt;br /&gt;
** use the commit message &amp;quot;Update for krb5-x.y.z-postrelease&amp;quot;&lt;br /&gt;
** push this commit to the authoritative repository&lt;/div&gt;</summary>
		<author><name>Ghudson</name></author>	</entry>

	<entry>
		<id>https://k5wiki.kerberos.org/wiki?title=Release_engineering_notes&amp;diff=6035</id>
		<title>Release engineering notes</title>
		<link rel="alternate" type="text/html" href="https://k5wiki.kerberos.org/wiki?title=Release_engineering_notes&amp;diff=6035"/>
				<updated>2023-04-13T21:47:23Z</updated>
		
		<summary type="html">&lt;p&gt;Ghudson: /* Creating a new release branch */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Release engineering environment==&lt;br /&gt;
&lt;br /&gt;
Release engineering operations are currently performed on a Ubuntu 18.04 host.  Updates to the Ubuntu version may cause churn in the generated files which are checked into the repository due to newer versions of programs in the toolchain.&lt;br /&gt;
&lt;br /&gt;
The release engineering host must have the following packages installed:&lt;br /&gt;
&lt;br /&gt;
* autoconf&lt;br /&gt;
* bison&lt;br /&gt;
* build-essential&lt;br /&gt;
* dejagnu&lt;br /&gt;
* doxygen&lt;br /&gt;
* flex&lt;br /&gt;
* git&lt;br /&gt;
* keyutils&lt;br /&gt;
* ldap-utils&lt;br /&gt;
* libcmocka-dev&lt;br /&gt;
* libkeyutils-dev&lt;br /&gt;
* libldap2-dev&lt;br /&gt;
* liblmdb-dev&lt;br /&gt;
* libresolv-wrapper&lt;br /&gt;
* libsasl2-dev&lt;br /&gt;
* libssl-dev&lt;br /&gt;
* libtool&lt;br /&gt;
* pkg-config&lt;br /&gt;
* python-sphinx&lt;br /&gt;
* python-cheetah&lt;br /&gt;
* rcs&lt;br /&gt;
* slapd&lt;br /&gt;
* tcl-dev&lt;br /&gt;
* texlive&lt;br /&gt;
* texlive-latex-extra&lt;br /&gt;
&lt;br /&gt;
==Pulling up changes to release branches==&lt;br /&gt;
&lt;br /&gt;
* For each supported release (usually the most recent and one previous release), prepare a git working copy with the krb5-x.y branch checked out from the authoritative repository.  From the krbdev-services repository, copy githooks/hookutils.py and githooks-client/prepare-commit-msg into .git/hooks for both working copies.&lt;br /&gt;
&lt;br /&gt;
* Check that each working copy is clean, has no unexpected extra commits, and is up to date with the authoritative repository.  Checking the output of &amp;quot;git status&amp;quot; and running &amp;quot;git pull&amp;quot; should accomplish this.&lt;br /&gt;
&lt;br /&gt;
* At https://krbdev.mit.edu:444/rt/ , start a new search, add the term &amp;quot;queue is krb5&amp;quot;, then the criteria &amp;quot;tags is pullup&amp;quot;, then search.  It can be useful to create a browser tab for each search result.&lt;br /&gt;
&lt;br /&gt;
* If there has been a calendar year change since the last patch release, pull up the commit(s) which bump the project-wide copyright years as well.&lt;br /&gt;
&lt;br /&gt;
* For each release branch:&lt;br /&gt;
** For each ticket marked for pullup to that branch:&lt;br /&gt;
*** For each commit listed in the ticket, run &amp;quot;KRB5_VERSION_FIXED=x.y.z git cherry-pick -x COMMIT&amp;quot;, and address any merge conflicts.  x.y.z should be the next patch release that will be created on the release branch.  If there are merge conflicts, &amp;quot;git cherry-pick --continue&amp;quot; will not apply the log message hook, so edit the RT fields manually.&lt;br /&gt;
*** Examine the commits any consider any possible interactions with changes made since the release branch.&lt;br /&gt;
*** Run &amp;quot;make&amp;quot; and &amp;quot;make check&amp;quot;.  Remember that &amp;quot;make check&amp;quot; will not work for multiple working directories concurrently on the same host.&lt;br /&gt;
*** If the change isn't covered by automated tests, consider testing it by hand.&lt;br /&gt;
* Consider pushing the updated release branches to a personal github fork integrated with Travis, and waiting for Travis to finish building and testing it.&lt;br /&gt;
* If the pulled up changes are substantial, consider running a build and check of each release branch on krbdev-sparc-build.&lt;br /&gt;
* Push the updated release branches to the authoritative repository.&lt;br /&gt;
* Remove the &amp;quot;pullup&amp;quot; tag from each ticket.  This can be done in a bulk update from the search result page, or it can be done on each ticket individually from the jumbo page.&lt;br /&gt;
&lt;br /&gt;
==Creating a new release branch==&lt;br /&gt;
&lt;br /&gt;
* At https://krbdev.mit.edu:444/rt/ , go to Admin -&amp;gt; Custom Fields -&amp;gt; Target_version and add x.y and x.y-next values.  Do the same for Version_Fixed.&lt;br /&gt;
* At https://krbdev.mit.edu:444/rt/ , perform a search with the following criteria:&lt;br /&gt;
** Queue is krb5&lt;br /&gt;
** Status is resolved&lt;br /&gt;
** Version_Fixed is (no value)&lt;br /&gt;
** Tags is not unsupported&lt;br /&gt;
** Tags is not noresource&lt;br /&gt;
** Tags is not nochange&lt;br /&gt;
* Verify that the resulting list of tickets are all for changes introduced in the past development cycle, and bulk update them to have Version_Fixed x.y.&lt;br /&gt;
* On the master branch, update doc/mitK5features.rst, updating the &amp;quot;Latest stable&amp;quot; and &amp;quot;Supported&amp;quot; release numbers.  Write up a list of major changes for the new release, broken down by category.  Code quality changes usually do not have associated tickets, so review the version history for commits with no RT headers.  Commit with the subject &amp;quot;Update features list for x.y&amp;quot;.&lt;br /&gt;
* On the master branch, update &amp;lt;code&amp;gt;config.guess&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;config.sub&amp;lt;/code&amp;gt; from &amp;lt;code&amp;gt;git://git.savannah.gnu.org/config.git&amp;lt;/code&amp;gt;.  Commit with the subject &amp;quot;Update config.guess, config.sub&amp;quot;&lt;br /&gt;
* On the master branch, run &amp;quot;make regen&amp;quot;.  Commit with the subject &amp;quot;make regen&amp;quot;.  Push the master branch to the authoritative repository.&lt;br /&gt;
* Create the new branch and push it to the authoritative repository.&lt;br /&gt;
* On the new branch, update README for the new release:&lt;br /&gt;
** Make sure that all x.y references are for the new version (they should be already).&lt;br /&gt;
** Update any notes about transitions (such as enctype deprecations) and add new ones if necessary.&lt;br /&gt;
** Include the list of major changes for the new release.&lt;br /&gt;
** Include the list of tickets changed (copy-paste from https://krbdev.mit.edu/rt/NoAuth/krb5-x.y/fixed-x.y.z.html).&lt;br /&gt;
** Copy the list of contributors from the previous release branch.&lt;br /&gt;
** Add contributors from the RT tickets for the new release branch.&lt;br /&gt;
** Commit with the message &amp;quot;Update README for krb5-x.y&amp;quot; and push to the authoritative repository.&lt;br /&gt;
* On the master branch, update README for the next prerelease:&lt;br /&gt;
** In README, update x.y references to x.(y+1).&lt;br /&gt;
** In README, copy the list of contributors from the x.y branch.&lt;br /&gt;
** In src/patchlevel.h, update KRB5_MINOR_RELEASE to y+1.&lt;br /&gt;
** Commit with the message &amp;quot;Updates for krb5-x.(y+1)-prerelease&amp;quot; and push to the authoritative repository.&lt;br /&gt;
* Update web pages&lt;br /&gt;
** Create directory /mit/kerberos/dist/krb5/x.y and copy HEADER from a previous directory&lt;br /&gt;
** Create directories /mit/kerberos/krb5-x.y and /mit/kerberos/krb5-x.y/RCS&lt;br /&gt;
&lt;br /&gt;
==Preparing releases==&lt;br /&gt;
&lt;br /&gt;
===Pre-mkrel===&lt;br /&gt;
&lt;br /&gt;
* check copyright years in project-wide stuff&lt;br /&gt;
* make sure you're in a build tree that's not the source tree and configured using &amp;lt;code&amp;gt;--enable-maintainer-mode&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;make depend&amp;lt;/code&amp;gt; and commit if changed, with the commit message &amp;quot;make depend&amp;quot;&lt;br /&gt;
* regenerate manpages: &amp;lt;code&amp;gt;(cd man &amp;amp;&amp;amp; make man)&amp;lt;/code&amp;gt; and commit if changed, with the commit message &amp;quot;Update man pages&amp;quot;&lt;br /&gt;
* regenerate localization template &amp;lt;code&amp;gt;(cd po &amp;amp;&amp;amp; make update-po)&amp;lt;/code&amp;gt; and commit if changed, with the commit message &amp;quot;make update-po&amp;quot;&lt;br /&gt;
* manually edit patchlevel.h to reflect the new release&lt;br /&gt;
** for a patch release, increment KRB5_PATCHLEVEL, change the next line to &amp;quot;/* #undef KRB5_RELTAIL */&amp;quot;, and change KRB5_RELTAG to &amp;quot;krb5-x.y.z-final&amp;quot;&lt;br /&gt;
** for an alpha or beta release, set KRB5_RELTAIL to &amp;quot;beta1&amp;quot; or similar, and change KRB5_RELTAG to &amp;quot;krb5-x.y-beta1&amp;quot; or similar.&lt;br /&gt;
* manually update README&lt;br /&gt;
** release dates (in major changes heading, ISO 8601 date format with hyphens)&lt;br /&gt;
*** we do not have release dates for alpha or beta releases; add one when making the first final x.y release&lt;br /&gt;
** changes&lt;br /&gt;
*** note whether bugfix release, maintenance vs current release&lt;br /&gt;
*** bullet list of major changes&lt;br /&gt;
*** minor changes = list of RT tickets fixed -- always grab a fresh list from RT when editing these!  (https://krbdev.mit.edu/rt/NoAuth/krb5-x.y/fixed-x.y.z.html)&lt;br /&gt;
** contributors (RT is a good source for these; click through the ticket links from the above URL and look for reporter and patch author names)&lt;br /&gt;
** double-check dates and release numbers in new section headings&lt;br /&gt;
* re-run &amp;lt;code&amp;gt;(cd man &amp;amp;&amp;amp; make man)&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;(cd po &amp;amp;&amp;amp; make update-po)&amp;lt;/code&amp;gt; with updated patchlevel.h&lt;br /&gt;
** If there is no update to Project-Id-Version in mit-krb5.pot, touch configure.in and re-run make, then run &amp;lt;code&amp;gt;(cd po &amp;amp;&amp;amp; make update-po)&amp;lt;/code&amp;gt; again.  (This should no longer be necessary after {{bug|8560}}.)&lt;br /&gt;
* commit the README, patchlevel-specific man page, and template changes with the subject &amp;quot;Update for krb5-x.y.z&amp;quot;&lt;br /&gt;
* &amp;lt;code&amp;gt;git tag krb5-x.y.z-final&amp;lt;/code&amp;gt; (or &amp;lt;code&amp;gt;krb5-x.y-beta1&amp;lt;/code&amp;gt; or similar for an alpha or beta release)&lt;br /&gt;
&lt;br /&gt;
===Running mkrel===&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;path_to_mkrel/mkrel --repository $YOUR_SOURCE_TREE krb5-x.y.z-final krb5-x.y.z&amp;lt;/code&amp;gt;&lt;br /&gt;
** For an alpha or beta release, &amp;lt;code&amp;gt;path_to_mkrel/mkrel --repository $YOUR_SOURCE_TREE krb5-x.y-beta1 krb5-x.y-beta1&amp;lt;/code&amp;gt; or similar&lt;br /&gt;
* manually inspect output for versioning and correctness&lt;br /&gt;
** HTML docs&lt;br /&gt;
** PDF docs&lt;br /&gt;
** patchlevel.h as modified by mkrel&lt;br /&gt;
* push release branch commits and release tags to authoritative repository&lt;br /&gt;
** you will need to be in hooks.branchers in the authoritative repository to push the tags&lt;br /&gt;
&lt;br /&gt;
===Post-mkrel===&lt;br /&gt;
&lt;br /&gt;
* PGP sign (&amp;lt;code&amp;gt;gpg -ab krb5-x.y.z.tar.gz&amp;lt;/code&amp;gt;, generates krb5-x.y.z.tar.gz.asc)&lt;br /&gt;
* copy tar file and signature into /mit/kerberos/dist/krb5/x.y&lt;br /&gt;
* for alpha and beta releases:&lt;br /&gt;
** create /mit/kerberos/krb5-x.y/krb5-x.y.html based on the first commit from a previous release&lt;br /&gt;
** symlink index.html to krb5-x.y.html in that directory&lt;br /&gt;
** place an entry in /mit/kerberos/dist/testing.html&lt;br /&gt;
** send an announcement to krbdev@mit.edu&lt;br /&gt;
** edit src/patchlevel.h, changing KRB5_RELTAIL to &amp;quot;beta1-postrelease&amp;quot; (or similar) and KRB5_RELTAG to &amp;quot;krb5-x.y&amp;quot;.  Commit with the subject &amp;quot;Update for krb5-x.y-beta1-postrelease&amp;quot; or similar and push to the authoritative repository.&lt;br /&gt;
** skip all remaining steps&lt;br /&gt;
* create /mit/kerberos/krb5-x.y/krb5-x.y.z and /mit/kerberos/krb5-x.y/krb5-x.y.z/doc&lt;br /&gt;
* copy signature to /mit/kerberos/krb5-x.y/krb5-x.y.z.sig&lt;br /&gt;
* copy README from release source code to /mit/kerberos/krb5-x.y/README-x.y.z.txt&lt;br /&gt;
* generate branded HTML docs&lt;br /&gt;
** &amp;lt;code&amp;gt;HTML_LOGO=/mit/kerberos/mitkc-logo-sm.png make html&amp;lt;/code&amp;gt;&lt;br /&gt;
** we don't ship the branded (with logo) docs because the logo is an MIT trademark&lt;br /&gt;
** copy the resulting documentation tree to /mit/kerberos/krb5-x.y/krb5-x.y.z/doc/html&lt;br /&gt;
** repeat for &amp;lt;code&amp;gt;HTML_LOGO=... make pdf&amp;lt;/code&amp;gt; and .../doc/pdf&lt;br /&gt;
* update RT configuration&lt;br /&gt;
** check that https://krbdev.mit.edu/rt/NoAuth/krb5-x.y/fixed-x.y.z.html and .../bugs-x.y.z.html work&lt;br /&gt;
** in the web interface, to go Admin -&amp;gt; Custom Fields -&amp;gt; Version_Fixed and add a new one for the next patch release&lt;br /&gt;
* edit web pages&lt;br /&gt;
** create /mit/kerberos/krb5-x.y/krb5-x.y.z.html and check it into RCS, using similar files as an example (for the first x.y release, update krb5-x.y.html using the previous release's krb5-x.y.html as an example)&lt;br /&gt;
** update /mit/kerberos/index.html with the new release numbers (possibly removing out-of-service releases) and add entries to the &amp;quot;Recent news&amp;quot; section; add old release entries to historical.html and old news items to oldnews.html&lt;br /&gt;
** update /mit/kerberos/dist/index.html with new release references (possibly removing out-of-service releases); add old entries to historic.html&lt;br /&gt;
** review edited web pages in a web browser and double check that release numbers and release dates have been updated&lt;br /&gt;
** update /mit/kerberos/krb5-x.y/doc and /mit/kerberos/krb5-x.y/index.html symlinks&lt;br /&gt;
** update /mit/kerberos/krb5-latest symlink if this is a major or minor release&lt;br /&gt;
** for the first final krb5-x.y release, remove the entry from /mit/kerberos/dist/testing.html&lt;br /&gt;
* send announcement to kerberos-announce&lt;br /&gt;
* make followup versioning commit to release branch&lt;br /&gt;
** edit src/patchlevel.h, setting KRB5_RELTAIL to &amp;quot;postrelease&amp;quot; and KRB5_RELTAG to &amp;quot;krb5-x.y&amp;quot;&lt;br /&gt;
** use the commit message &amp;quot;Update for krb5-x.y.z-postrelease&amp;quot;&lt;br /&gt;
** push this commit to the authoritative repository&lt;/div&gt;</summary>
		<author><name>Ghudson</name></author>	</entry>

	<entry>
		<id>https://k5wiki.kerberos.org/wiki?title=Release_engineering_notes&amp;diff=6034</id>
		<title>Release engineering notes</title>
		<link rel="alternate" type="text/html" href="https://k5wiki.kerberos.org/wiki?title=Release_engineering_notes&amp;diff=6034"/>
				<updated>2023-04-13T21:25:49Z</updated>
		
		<summary type="html">&lt;p&gt;Ghudson: /* Creating a new release branch */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Release engineering environment==&lt;br /&gt;
&lt;br /&gt;
Release engineering operations are currently performed on a Ubuntu 18.04 host.  Updates to the Ubuntu version may cause churn in the generated files which are checked into the repository due to newer versions of programs in the toolchain.&lt;br /&gt;
&lt;br /&gt;
The release engineering host must have the following packages installed:&lt;br /&gt;
&lt;br /&gt;
* autoconf&lt;br /&gt;
* bison&lt;br /&gt;
* build-essential&lt;br /&gt;
* dejagnu&lt;br /&gt;
* doxygen&lt;br /&gt;
* flex&lt;br /&gt;
* git&lt;br /&gt;
* keyutils&lt;br /&gt;
* ldap-utils&lt;br /&gt;
* libcmocka-dev&lt;br /&gt;
* libkeyutils-dev&lt;br /&gt;
* libldap2-dev&lt;br /&gt;
* liblmdb-dev&lt;br /&gt;
* libresolv-wrapper&lt;br /&gt;
* libsasl2-dev&lt;br /&gt;
* libssl-dev&lt;br /&gt;
* libtool&lt;br /&gt;
* pkg-config&lt;br /&gt;
* python-sphinx&lt;br /&gt;
* python-cheetah&lt;br /&gt;
* rcs&lt;br /&gt;
* slapd&lt;br /&gt;
* tcl-dev&lt;br /&gt;
* texlive&lt;br /&gt;
* texlive-latex-extra&lt;br /&gt;
&lt;br /&gt;
==Pulling up changes to release branches==&lt;br /&gt;
&lt;br /&gt;
* For each supported release (usually the most recent and one previous release), prepare a git working copy with the krb5-x.y branch checked out from the authoritative repository.  From the krbdev-services repository, copy githooks/hookutils.py and githooks-client/prepare-commit-msg into .git/hooks for both working copies.&lt;br /&gt;
&lt;br /&gt;
* Check that each working copy is clean, has no unexpected extra commits, and is up to date with the authoritative repository.  Checking the output of &amp;quot;git status&amp;quot; and running &amp;quot;git pull&amp;quot; should accomplish this.&lt;br /&gt;
&lt;br /&gt;
* At https://krbdev.mit.edu:444/rt/ , start a new search, add the term &amp;quot;queue is krb5&amp;quot;, then the criteria &amp;quot;tags is pullup&amp;quot;, then search.  It can be useful to create a browser tab for each search result.&lt;br /&gt;
&lt;br /&gt;
* If there has been a calendar year change since the last patch release, pull up the commit(s) which bump the project-wide copyright years as well.&lt;br /&gt;
&lt;br /&gt;
* For each release branch:&lt;br /&gt;
** For each ticket marked for pullup to that branch:&lt;br /&gt;
*** For each commit listed in the ticket, run &amp;quot;KRB5_VERSION_FIXED=x.y.z git cherry-pick -x COMMIT&amp;quot;, and address any merge conflicts.  x.y.z should be the next patch release that will be created on the release branch.  If there are merge conflicts, &amp;quot;git cherry-pick --continue&amp;quot; will not apply the log message hook, so edit the RT fields manually.&lt;br /&gt;
*** Examine the commits any consider any possible interactions with changes made since the release branch.&lt;br /&gt;
*** Run &amp;quot;make&amp;quot; and &amp;quot;make check&amp;quot;.  Remember that &amp;quot;make check&amp;quot; will not work for multiple working directories concurrently on the same host.&lt;br /&gt;
*** If the change isn't covered by automated tests, consider testing it by hand.&lt;br /&gt;
* Consider pushing the updated release branches to a personal github fork integrated with Travis, and waiting for Travis to finish building and testing it.&lt;br /&gt;
* If the pulled up changes are substantial, consider running a build and check of each release branch on krbdev-sparc-build.&lt;br /&gt;
* Push the updated release branches to the authoritative repository.&lt;br /&gt;
* Remove the &amp;quot;pullup&amp;quot; tag from each ticket.  This can be done in a bulk update from the search result page, or it can be done on each ticket individually from the jumbo page.&lt;br /&gt;
&lt;br /&gt;
==Creating a new release branch==&lt;br /&gt;
&lt;br /&gt;
* At https://krbdev.mit.edu:444/rt/ , go to Admin -&amp;gt; Custom Fields -&amp;gt; Target_version and add x.y and x.y-next values.  Do the same for Version_Fixed.&lt;br /&gt;
* At https://krbdev.mit.edu:444/rt/ , perform a search with the following criteria:&lt;br /&gt;
** Queue is krb5&lt;br /&gt;
** Status is resolved&lt;br /&gt;
** Version_Fixed is (no value)&lt;br /&gt;
** Tags is not unsupported&lt;br /&gt;
** Tags is not noresource&lt;br /&gt;
** Tags is not nochange&lt;br /&gt;
* Verify that the resulting list of tickets are all for changes introduced in the past development cycle, and bulk update them to have Version_Fixed x.y.&lt;br /&gt;
* On the master branch, update doc/mitK5features.rst, updating the &amp;quot;Latest stable&amp;quot; and &amp;quot;Supported&amp;quot; release numbers.  Write up a list of major changes for the new release, broken down by category.  Code quality changes usually do not have associated tickets, so review the version history for commits with no RT headers.  Commit with the subject &amp;quot;Update features list for x.y&amp;quot;.&lt;br /&gt;
* On the master branch, update &amp;lt;code&amp;gt;config.guess&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;config.sub&amp;lt;/code&amp;gt; from &amp;lt;code&amp;gt;git://git.savannah.gnu.org/config.git&amp;lt;/code&amp;gt;.  Commit with the subject &amp;quot;Update config.guess, config.sub&amp;quot;&lt;br /&gt;
* On the master branch, run &amp;quot;make regen&amp;quot;.  Commit with the subject &amp;quot;make regen&amp;quot;.  Push the master branch to the authoritative repository.&lt;br /&gt;
* Create the new branch and push it to the authoritative repository.&lt;br /&gt;
* On the new branch, update README for the new release:&lt;br /&gt;
** Make sure that all x.y references are for the new version (they should be already).&lt;br /&gt;
** Include the list of major changes for the new release.&lt;br /&gt;
** Include the list of tickets changed (copy-paste from https://krbdev.mit.edu/rt/NoAuth/krb5-x.y/fixed-x.y.z.html).&lt;br /&gt;
** Copy the list of contributors from the previous release branch.&lt;br /&gt;
** Add contributors from the RT tickets for the new release branch.&lt;br /&gt;
** Commit with the message &amp;quot;Update README for krb5-x.y&amp;quot; and push to the authoritative repository.&lt;br /&gt;
* On the master branch, update README for the next prerelease:&lt;br /&gt;
** In README, update x.y references to x.(y+1).&lt;br /&gt;
** In README, copy the list of contributors from the x.y branch.&lt;br /&gt;
** In src/patchlevel.h, update KRB5_MINOR_RELEASE to y+1.&lt;br /&gt;
** Commit with the message &amp;quot;Updates for krb5-x.(y+1)-prerelease&amp;quot; and push to the authoritative repository.&lt;br /&gt;
* Update web pages&lt;br /&gt;
** Create directory /mit/kerberos/dist/krb5/x.y and copy HEADER from a previous directory&lt;br /&gt;
** Create directories /mit/kerberos/krb5-x.y and /mit/kerberos/krb5-x.y/RCS&lt;br /&gt;
&lt;br /&gt;
==Preparing releases==&lt;br /&gt;
&lt;br /&gt;
===Pre-mkrel===&lt;br /&gt;
&lt;br /&gt;
* check copyright years in project-wide stuff&lt;br /&gt;
* make sure you're in a build tree that's not the source tree and configured using &amp;lt;code&amp;gt;--enable-maintainer-mode&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;make depend&amp;lt;/code&amp;gt; and commit if changed, with the commit message &amp;quot;make depend&amp;quot;&lt;br /&gt;
* regenerate manpages: &amp;lt;code&amp;gt;(cd man &amp;amp;&amp;amp; make man)&amp;lt;/code&amp;gt; and commit if changed, with the commit message &amp;quot;Update man pages&amp;quot;&lt;br /&gt;
* regenerate localization template &amp;lt;code&amp;gt;(cd po &amp;amp;&amp;amp; make update-po)&amp;lt;/code&amp;gt; and commit if changed, with the commit message &amp;quot;make update-po&amp;quot;&lt;br /&gt;
* manually edit patchlevel.h to reflect the new release&lt;br /&gt;
** for a patch release, increment KRB5_PATCHLEVEL, change the next line to &amp;quot;/* #undef KRB5_RELTAIL */&amp;quot;, and change KRB5_RELTAG to &amp;quot;krb5-x.y.z-final&amp;quot;&lt;br /&gt;
** for an alpha or beta release, set KRB5_RELTAIL to &amp;quot;beta1&amp;quot; or similar, and change KRB5_RELTAG to &amp;quot;krb5-x.y-beta1&amp;quot; or similar.&lt;br /&gt;
* manually update README&lt;br /&gt;
** release dates (in major changes heading, ISO 8601 date format with hyphens)&lt;br /&gt;
*** we do not have release dates for alpha or beta releases; add one when making the first final x.y release&lt;br /&gt;
** changes&lt;br /&gt;
*** note whether bugfix release, maintenance vs current release&lt;br /&gt;
*** bullet list of major changes&lt;br /&gt;
*** minor changes = list of RT tickets fixed -- always grab a fresh list from RT when editing these!  (https://krbdev.mit.edu/rt/NoAuth/krb5-x.y/fixed-x.y.z.html)&lt;br /&gt;
** contributors (RT is a good source for these; click through the ticket links from the above URL and look for reporter and patch author names)&lt;br /&gt;
** double-check dates and release numbers in new section headings&lt;br /&gt;
* re-run &amp;lt;code&amp;gt;(cd man &amp;amp;&amp;amp; make man)&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;(cd po &amp;amp;&amp;amp; make update-po)&amp;lt;/code&amp;gt; with updated patchlevel.h&lt;br /&gt;
** If there is no update to Project-Id-Version in mit-krb5.pot, touch configure.in and re-run make, then run &amp;lt;code&amp;gt;(cd po &amp;amp;&amp;amp; make update-po)&amp;lt;/code&amp;gt; again.  (This should no longer be necessary after {{bug|8560}}.)&lt;br /&gt;
* commit the README, patchlevel-specific man page, and template changes with the subject &amp;quot;Update for krb5-x.y.z&amp;quot;&lt;br /&gt;
* &amp;lt;code&amp;gt;git tag krb5-x.y.z-final&amp;lt;/code&amp;gt; (or &amp;lt;code&amp;gt;krb5-x.y-beta1&amp;lt;/code&amp;gt; or similar for an alpha or beta release)&lt;br /&gt;
&lt;br /&gt;
===Running mkrel===&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;path_to_mkrel/mkrel --repository $YOUR_SOURCE_TREE krb5-x.y.z-final krb5-x.y.z&amp;lt;/code&amp;gt;&lt;br /&gt;
** For an alpha or beta release, &amp;lt;code&amp;gt;path_to_mkrel/mkrel --repository $YOUR_SOURCE_TREE krb5-x.y-beta1 krb5-x.y-beta1&amp;lt;/code&amp;gt; or similar&lt;br /&gt;
* manually inspect output for versioning and correctness&lt;br /&gt;
** HTML docs&lt;br /&gt;
** PDF docs&lt;br /&gt;
** patchlevel.h as modified by mkrel&lt;br /&gt;
* push release branch commits and release tags to authoritative repository&lt;br /&gt;
** you will need to be in hooks.branchers in the authoritative repository to push the tags&lt;br /&gt;
&lt;br /&gt;
===Post-mkrel===&lt;br /&gt;
&lt;br /&gt;
* PGP sign (&amp;lt;code&amp;gt;gpg -ab krb5-x.y.z.tar.gz&amp;lt;/code&amp;gt;, generates krb5-x.y.z.tar.gz.asc)&lt;br /&gt;
* copy tar file and signature into /mit/kerberos/dist/krb5/x.y&lt;br /&gt;
* for alpha and beta releases:&lt;br /&gt;
** create /mit/kerberos/krb5-x.y/krb5-x.y.html based on the first commit from a previous release&lt;br /&gt;
** symlink index.html to krb5-x.y.html in that directory&lt;br /&gt;
** place an entry in /mit/kerberos/dist/testing.html&lt;br /&gt;
** send an announcement to krbdev@mit.edu&lt;br /&gt;
** edit src/patchlevel.h, changing KRB5_RELTAIL to &amp;quot;beta1-postrelease&amp;quot; (or similar) and KRB5_RELTAG to &amp;quot;krb5-x.y&amp;quot;.  Commit with the subject &amp;quot;Update for krb5-x.y-beta1-postrelease&amp;quot; or similar and push to the authoritative repository.&lt;br /&gt;
** skip all remaining steps&lt;br /&gt;
* create /mit/kerberos/krb5-x.y/krb5-x.y.z and /mit/kerberos/krb5-x.y/krb5-x.y.z/doc&lt;br /&gt;
* copy signature to /mit/kerberos/krb5-x.y/krb5-x.y.z.sig&lt;br /&gt;
* copy README from release source code to /mit/kerberos/krb5-x.y/README-x.y.z.txt&lt;br /&gt;
* generate branded HTML docs&lt;br /&gt;
** &amp;lt;code&amp;gt;HTML_LOGO=/mit/kerberos/mitkc-logo-sm.png make html&amp;lt;/code&amp;gt;&lt;br /&gt;
** we don't ship the branded (with logo) docs because the logo is an MIT trademark&lt;br /&gt;
** copy the resulting documentation tree to /mit/kerberos/krb5-x.y/krb5-x.y.z/doc/html&lt;br /&gt;
** repeat for &amp;lt;code&amp;gt;HTML_LOGO=... make pdf&amp;lt;/code&amp;gt; and .../doc/pdf&lt;br /&gt;
* update RT configuration&lt;br /&gt;
** check that https://krbdev.mit.edu/rt/NoAuth/krb5-x.y/fixed-x.y.z.html and .../bugs-x.y.z.html work&lt;br /&gt;
** in the web interface, to go Admin -&amp;gt; Custom Fields -&amp;gt; Version_Fixed and add a new one for the next patch release&lt;br /&gt;
* edit web pages&lt;br /&gt;
** create /mit/kerberos/krb5-x.y/krb5-x.y.z.html and check it into RCS, using similar files as an example (for the first x.y release, update krb5-x.y.html using the previous release's krb5-x.y.html as an example)&lt;br /&gt;
** update /mit/kerberos/index.html with the new release numbers (possibly removing out-of-service releases) and add entries to the &amp;quot;Recent news&amp;quot; section; add old release entries to historical.html and old news items to oldnews.html&lt;br /&gt;
** update /mit/kerberos/dist/index.html with new release references (possibly removing out-of-service releases); add old entries to historic.html&lt;br /&gt;
** review edited web pages in a web browser and double check that release numbers and release dates have been updated&lt;br /&gt;
** update /mit/kerberos/krb5-x.y/doc and /mit/kerberos/krb5-x.y/index.html symlinks&lt;br /&gt;
** update /mit/kerberos/krb5-latest symlink if this is a major or minor release&lt;br /&gt;
** for the first final krb5-x.y release, remove the entry from /mit/kerberos/dist/testing.html&lt;br /&gt;
* send announcement to kerberos-announce&lt;br /&gt;
* make followup versioning commit to release branch&lt;br /&gt;
** edit src/patchlevel.h, setting KRB5_RELTAIL to &amp;quot;postrelease&amp;quot; and KRB5_RELTAG to &amp;quot;krb5-x.y&amp;quot;&lt;br /&gt;
** use the commit message &amp;quot;Update for krb5-x.y.z-postrelease&amp;quot;&lt;br /&gt;
** push this commit to the authoritative repository&lt;/div&gt;</summary>
		<author><name>Ghudson</name></author>	</entry>

	<entry>
		<id>https://k5wiki.kerberos.org/wiki?title=Release_engineering_notes&amp;diff=6033</id>
		<title>Release engineering notes</title>
		<link rel="alternate" type="text/html" href="https://k5wiki.kerberos.org/wiki?title=Release_engineering_notes&amp;diff=6033"/>
				<updated>2023-04-13T21:14:23Z</updated>
		
		<summary type="html">&lt;p&gt;Ghudson: /* Creating a new release branch */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Release engineering environment==&lt;br /&gt;
&lt;br /&gt;
Release engineering operations are currently performed on a Ubuntu 18.04 host.  Updates to the Ubuntu version may cause churn in the generated files which are checked into the repository due to newer versions of programs in the toolchain.&lt;br /&gt;
&lt;br /&gt;
The release engineering host must have the following packages installed:&lt;br /&gt;
&lt;br /&gt;
* autoconf&lt;br /&gt;
* bison&lt;br /&gt;
* build-essential&lt;br /&gt;
* dejagnu&lt;br /&gt;
* doxygen&lt;br /&gt;
* flex&lt;br /&gt;
* git&lt;br /&gt;
* keyutils&lt;br /&gt;
* ldap-utils&lt;br /&gt;
* libcmocka-dev&lt;br /&gt;
* libkeyutils-dev&lt;br /&gt;
* libldap2-dev&lt;br /&gt;
* liblmdb-dev&lt;br /&gt;
* libresolv-wrapper&lt;br /&gt;
* libsasl2-dev&lt;br /&gt;
* libssl-dev&lt;br /&gt;
* libtool&lt;br /&gt;
* pkg-config&lt;br /&gt;
* python-sphinx&lt;br /&gt;
* python-cheetah&lt;br /&gt;
* rcs&lt;br /&gt;
* slapd&lt;br /&gt;
* tcl-dev&lt;br /&gt;
* texlive&lt;br /&gt;
* texlive-latex-extra&lt;br /&gt;
&lt;br /&gt;
==Pulling up changes to release branches==&lt;br /&gt;
&lt;br /&gt;
* For each supported release (usually the most recent and one previous release), prepare a git working copy with the krb5-x.y branch checked out from the authoritative repository.  From the krbdev-services repository, copy githooks/hookutils.py and githooks-client/prepare-commit-msg into .git/hooks for both working copies.&lt;br /&gt;
&lt;br /&gt;
* Check that each working copy is clean, has no unexpected extra commits, and is up to date with the authoritative repository.  Checking the output of &amp;quot;git status&amp;quot; and running &amp;quot;git pull&amp;quot; should accomplish this.&lt;br /&gt;
&lt;br /&gt;
* At https://krbdev.mit.edu:444/rt/ , start a new search, add the term &amp;quot;queue is krb5&amp;quot;, then the criteria &amp;quot;tags is pullup&amp;quot;, then search.  It can be useful to create a browser tab for each search result.&lt;br /&gt;
&lt;br /&gt;
* If there has been a calendar year change since the last patch release, pull up the commit(s) which bump the project-wide copyright years as well.&lt;br /&gt;
&lt;br /&gt;
* For each release branch:&lt;br /&gt;
** For each ticket marked for pullup to that branch:&lt;br /&gt;
*** For each commit listed in the ticket, run &amp;quot;KRB5_VERSION_FIXED=x.y.z git cherry-pick -x COMMIT&amp;quot;, and address any merge conflicts.  x.y.z should be the next patch release that will be created on the release branch.  If there are merge conflicts, &amp;quot;git cherry-pick --continue&amp;quot; will not apply the log message hook, so edit the RT fields manually.&lt;br /&gt;
*** Examine the commits any consider any possible interactions with changes made since the release branch.&lt;br /&gt;
*** Run &amp;quot;make&amp;quot; and &amp;quot;make check&amp;quot;.  Remember that &amp;quot;make check&amp;quot; will not work for multiple working directories concurrently on the same host.&lt;br /&gt;
*** If the change isn't covered by automated tests, consider testing it by hand.&lt;br /&gt;
* Consider pushing the updated release branches to a personal github fork integrated with Travis, and waiting for Travis to finish building and testing it.&lt;br /&gt;
* If the pulled up changes are substantial, consider running a build and check of each release branch on krbdev-sparc-build.&lt;br /&gt;
* Push the updated release branches to the authoritative repository.&lt;br /&gt;
* Remove the &amp;quot;pullup&amp;quot; tag from each ticket.  This can be done in a bulk update from the search result page, or it can be done on each ticket individually from the jumbo page.&lt;br /&gt;
&lt;br /&gt;
==Creating a new release branch==&lt;br /&gt;
&lt;br /&gt;
* At https://krbdev.mit.edu:444/rt/ , go to Admin -&amp;gt; Custom Fields -&amp;gt; Target_version and add x.y and x.y-next values.  Do the same for Version_Fixed.&lt;br /&gt;
* At https://krbdev.mit.edu:444/rt/ , perform a search with the following criteria:&lt;br /&gt;
** Queue is krb5&lt;br /&gt;
** Status is resolved&lt;br /&gt;
** Version_Fixed is (no value)&lt;br /&gt;
** Tags is not unsupported&lt;br /&gt;
** Tags is not noresource&lt;br /&gt;
** Tags is not nochange&lt;br /&gt;
* Verify that the resulting list of tickets are all for changes introduced in the past development cycle, and bulk update them to have Version_Fixed x.y.&lt;br /&gt;
* On the master branch, update doc/mitK5features.rst, updating the &amp;quot;Latest stable&amp;quot; and &amp;quot;Supported&amp;quot; release numbers.  Write up a list of major changes for the new release, broken down by category.  Code quality changes usually do not have associated tickets, so review the version history for commits with no RT headers.  Commit with the subject &amp;quot;Update features list for x.y&amp;quot; and push to the authoritative repository.&lt;br /&gt;
* On the master branch, update &amp;lt;code&amp;gt;config.guess&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;config.sub&amp;lt;/code&amp;gt; from &amp;lt;code&amp;gt;git://git.savannah.gnu.org/config.git&amp;lt;/code&amp;gt;.  Commit with the subject &amp;quot;Update config.guess, config.sub&amp;quot; and push to the authoritative repository.&lt;br /&gt;
* Create the new branch and push it to the authoritative repository.&lt;br /&gt;
* On the new branch, update README for the new release:&lt;br /&gt;
** Make sure that all x.y references are for the new version (they should be already).&lt;br /&gt;
** Include the list of major changes for the new release.&lt;br /&gt;
** Include the list of tickets changed (copy-paste from https://krbdev.mit.edu/rt/NoAuth/krb5-x.y/fixed-x.y.z.html).&lt;br /&gt;
** Copy the list of contributors from the previous release branch.&lt;br /&gt;
** Add contributors from the RT tickets for the new release branch.&lt;br /&gt;
** Commit with the message &amp;quot;Update README for krb5-x.y&amp;quot; and push to the authoritative repository.&lt;br /&gt;
* On the master branch, update README for the next prerelease:&lt;br /&gt;
** In README, update x.y references to x.(y+1).&lt;br /&gt;
** In README, copy the list of contributors from the x.y branch.&lt;br /&gt;
** In src/patchlevel.h, update KRB5_MINOR_RELEASE to y+1.&lt;br /&gt;
** Commit with the message &amp;quot;Updates for krb5-x.(y+1)-prerelease&amp;quot; and push to the authoritative repository.&lt;br /&gt;
* Update web pages&lt;br /&gt;
** Create directory /mit/kerberos/dist/krb5/x.y and copy HEADER from a previous directory&lt;br /&gt;
** Create directories /mit/kerberos/krb5-x.y and /mit/kerberos/krb5-x.y/RCS&lt;br /&gt;
&lt;br /&gt;
==Preparing releases==&lt;br /&gt;
&lt;br /&gt;
===Pre-mkrel===&lt;br /&gt;
&lt;br /&gt;
* check copyright years in project-wide stuff&lt;br /&gt;
* make sure you're in a build tree that's not the source tree and configured using &amp;lt;code&amp;gt;--enable-maintainer-mode&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;make depend&amp;lt;/code&amp;gt; and commit if changed, with the commit message &amp;quot;make depend&amp;quot;&lt;br /&gt;
* regenerate manpages: &amp;lt;code&amp;gt;(cd man &amp;amp;&amp;amp; make man)&amp;lt;/code&amp;gt; and commit if changed, with the commit message &amp;quot;Update man pages&amp;quot;&lt;br /&gt;
* regenerate localization template &amp;lt;code&amp;gt;(cd po &amp;amp;&amp;amp; make update-po)&amp;lt;/code&amp;gt; and commit if changed, with the commit message &amp;quot;make update-po&amp;quot;&lt;br /&gt;
* manually edit patchlevel.h to reflect the new release&lt;br /&gt;
** for a patch release, increment KRB5_PATCHLEVEL, change the next line to &amp;quot;/* #undef KRB5_RELTAIL */&amp;quot;, and change KRB5_RELTAG to &amp;quot;krb5-x.y.z-final&amp;quot;&lt;br /&gt;
** for an alpha or beta release, set KRB5_RELTAIL to &amp;quot;beta1&amp;quot; or similar, and change KRB5_RELTAG to &amp;quot;krb5-x.y-beta1&amp;quot; or similar.&lt;br /&gt;
* manually update README&lt;br /&gt;
** release dates (in major changes heading, ISO 8601 date format with hyphens)&lt;br /&gt;
*** we do not have release dates for alpha or beta releases; add one when making the first final x.y release&lt;br /&gt;
** changes&lt;br /&gt;
*** note whether bugfix release, maintenance vs current release&lt;br /&gt;
*** bullet list of major changes&lt;br /&gt;
*** minor changes = list of RT tickets fixed -- always grab a fresh list from RT when editing these!  (https://krbdev.mit.edu/rt/NoAuth/krb5-x.y/fixed-x.y.z.html)&lt;br /&gt;
** contributors (RT is a good source for these; click through the ticket links from the above URL and look for reporter and patch author names)&lt;br /&gt;
** double-check dates and release numbers in new section headings&lt;br /&gt;
* re-run &amp;lt;code&amp;gt;(cd man &amp;amp;&amp;amp; make man)&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;(cd po &amp;amp;&amp;amp; make update-po)&amp;lt;/code&amp;gt; with updated patchlevel.h&lt;br /&gt;
** If there is no update to Project-Id-Version in mit-krb5.pot, touch configure.in and re-run make, then run &amp;lt;code&amp;gt;(cd po &amp;amp;&amp;amp; make update-po)&amp;lt;/code&amp;gt; again.  (This should no longer be necessary after {{bug|8560}}.)&lt;br /&gt;
* commit the README, patchlevel-specific man page, and template changes with the subject &amp;quot;Update for krb5-x.y.z&amp;quot;&lt;br /&gt;
* &amp;lt;code&amp;gt;git tag krb5-x.y.z-final&amp;lt;/code&amp;gt; (or &amp;lt;code&amp;gt;krb5-x.y-beta1&amp;lt;/code&amp;gt; or similar for an alpha or beta release)&lt;br /&gt;
&lt;br /&gt;
===Running mkrel===&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;path_to_mkrel/mkrel --repository $YOUR_SOURCE_TREE krb5-x.y.z-final krb5-x.y.z&amp;lt;/code&amp;gt;&lt;br /&gt;
** For an alpha or beta release, &amp;lt;code&amp;gt;path_to_mkrel/mkrel --repository $YOUR_SOURCE_TREE krb5-x.y-beta1 krb5-x.y-beta1&amp;lt;/code&amp;gt; or similar&lt;br /&gt;
* manually inspect output for versioning and correctness&lt;br /&gt;
** HTML docs&lt;br /&gt;
** PDF docs&lt;br /&gt;
** patchlevel.h as modified by mkrel&lt;br /&gt;
* push release branch commits and release tags to authoritative repository&lt;br /&gt;
** you will need to be in hooks.branchers in the authoritative repository to push the tags&lt;br /&gt;
&lt;br /&gt;
===Post-mkrel===&lt;br /&gt;
&lt;br /&gt;
* PGP sign (&amp;lt;code&amp;gt;gpg -ab krb5-x.y.z.tar.gz&amp;lt;/code&amp;gt;, generates krb5-x.y.z.tar.gz.asc)&lt;br /&gt;
* copy tar file and signature into /mit/kerberos/dist/krb5/x.y&lt;br /&gt;
* for alpha and beta releases:&lt;br /&gt;
** create /mit/kerberos/krb5-x.y/krb5-x.y.html based on the first commit from a previous release&lt;br /&gt;
** symlink index.html to krb5-x.y.html in that directory&lt;br /&gt;
** place an entry in /mit/kerberos/dist/testing.html&lt;br /&gt;
** send an announcement to krbdev@mit.edu&lt;br /&gt;
** edit src/patchlevel.h, changing KRB5_RELTAIL to &amp;quot;beta1-postrelease&amp;quot; (or similar) and KRB5_RELTAG to &amp;quot;krb5-x.y&amp;quot;.  Commit with the subject &amp;quot;Update for krb5-x.y-beta1-postrelease&amp;quot; or similar and push to the authoritative repository.&lt;br /&gt;
** skip all remaining steps&lt;br /&gt;
* create /mit/kerberos/krb5-x.y/krb5-x.y.z and /mit/kerberos/krb5-x.y/krb5-x.y.z/doc&lt;br /&gt;
* copy signature to /mit/kerberos/krb5-x.y/krb5-x.y.z.sig&lt;br /&gt;
* copy README from release source code to /mit/kerberos/krb5-x.y/README-x.y.z.txt&lt;br /&gt;
* generate branded HTML docs&lt;br /&gt;
** &amp;lt;code&amp;gt;HTML_LOGO=/mit/kerberos/mitkc-logo-sm.png make html&amp;lt;/code&amp;gt;&lt;br /&gt;
** we don't ship the branded (with logo) docs because the logo is an MIT trademark&lt;br /&gt;
** copy the resulting documentation tree to /mit/kerberos/krb5-x.y/krb5-x.y.z/doc/html&lt;br /&gt;
** repeat for &amp;lt;code&amp;gt;HTML_LOGO=... make pdf&amp;lt;/code&amp;gt; and .../doc/pdf&lt;br /&gt;
* update RT configuration&lt;br /&gt;
** check that https://krbdev.mit.edu/rt/NoAuth/krb5-x.y/fixed-x.y.z.html and .../bugs-x.y.z.html work&lt;br /&gt;
** in the web interface, to go Admin -&amp;gt; Custom Fields -&amp;gt; Version_Fixed and add a new one for the next patch release&lt;br /&gt;
* edit web pages&lt;br /&gt;
** create /mit/kerberos/krb5-x.y/krb5-x.y.z.html and check it into RCS, using similar files as an example (for the first x.y release, update krb5-x.y.html using the previous release's krb5-x.y.html as an example)&lt;br /&gt;
** update /mit/kerberos/index.html with the new release numbers (possibly removing out-of-service releases) and add entries to the &amp;quot;Recent news&amp;quot; section; add old release entries to historical.html and old news items to oldnews.html&lt;br /&gt;
** update /mit/kerberos/dist/index.html with new release references (possibly removing out-of-service releases); add old entries to historic.html&lt;br /&gt;
** review edited web pages in a web browser and double check that release numbers and release dates have been updated&lt;br /&gt;
** update /mit/kerberos/krb5-x.y/doc and /mit/kerberos/krb5-x.y/index.html symlinks&lt;br /&gt;
** update /mit/kerberos/krb5-latest symlink if this is a major or minor release&lt;br /&gt;
** for the first final krb5-x.y release, remove the entry from /mit/kerberos/dist/testing.html&lt;br /&gt;
* send announcement to kerberos-announce&lt;br /&gt;
* make followup versioning commit to release branch&lt;br /&gt;
** edit src/patchlevel.h, setting KRB5_RELTAIL to &amp;quot;postrelease&amp;quot; and KRB5_RELTAG to &amp;quot;krb5-x.y&amp;quot;&lt;br /&gt;
** use the commit message &amp;quot;Update for krb5-x.y.z-postrelease&amp;quot;&lt;br /&gt;
** push this commit to the authoritative repository&lt;/div&gt;</summary>
		<author><name>Ghudson</name></author>	</entry>

	<entry>
		<id>https://k5wiki.kerberos.org/wiki?title=Committer_resources&amp;diff=6032</id>
		<title>Committer resources</title>
		<link rel="alternate" type="text/html" href="https://k5wiki.kerberos.org/wiki?title=Committer_resources&amp;diff=6032"/>
				<updated>2022-04-13T18:17:58Z</updated>
		
		<summary type="html">&lt;p&gt;Ghudson: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This is information for developers who are [[Committers|committers]] to our repository.&lt;br /&gt;
&lt;br /&gt;
== Enrollment ==&lt;br /&gt;
&lt;br /&gt;
* Athena account: MITKC staff will sponsor as appropriate.  See http://web.mit.edu/accounts/www/getaccount.html for some overview information about Athena accounts.&lt;br /&gt;
* X.509 client certificate: Needed for RT access, among others.  Information on how to obtain one is at http://web.mit.edu/ist/topics/certificates/index.html&lt;br /&gt;
* RT account&lt;br /&gt;
* Git access&lt;br /&gt;
* Posting authorization to cvs-krb5 if you are going to commit stuff.&lt;br /&gt;
* Coverity scan access&lt;br /&gt;
&lt;br /&gt;
== Where stuff is at ==&lt;br /&gt;
&lt;br /&gt;
* Git URL: krbdev.mit.edu:/git/krb5.git -- you may need to put &amp;quot;username@&amp;quot; in front if your local username is not the same as your Athena account name.  Clone this instead of git@github.com:krb5/krb5.git when setting up your local repository in order to be able to push changes.&lt;br /&gt;
* SSH to athena.dialup.mit.edu if you want easy access to AFS, a UNIX shell, etc.&lt;br /&gt;
** You'll need to set GSSAPIDelegateCredentials=yes in order to do passwordless login, because user home directories are in AFS, and the administrators didn't want to confuse users who logged in with Kerberos but couldn't access their files.&lt;br /&gt;
* RT https://krbdev.mit.edu/rt/ (or https://krbdev.mit.edu:444/rt/ if your browser doesn't deal with &amp;quot;optional&amp;quot; SSL client certificate verification)&lt;br /&gt;
&lt;br /&gt;
== Accessing krbdev.mit.edu ==&lt;br /&gt;
&lt;br /&gt;
The preferred way to access krbdev.mit.edu is with GSSAPI krb5 authentication.  It is not necessary to delegate credentials.  publickey authentication can be set up if required.&lt;br /&gt;
&lt;br /&gt;
== RT headers ==&lt;br /&gt;
&lt;br /&gt;
If a commit makes a user-visible change, such as adding a new feature or fixing a user-visible bug in a previous release, it should be associated with an RT ticket.  Do this by adding RT pseudo-headers at the end of the commit message, after a blank line.  The most important header is &amp;quot;ticket:&amp;quot;, which associates the commit with a ticket number.  Add &amp;quot;tags: pullup&amp;quot; and &amp;quot;target_version: X.Y-next&amp;quot; if the commit should be pulled up to a release branch.  Here is an example:&lt;br /&gt;
&lt;br /&gt;
    Use correct profile var in krb5_get_tgs_ktypes&lt;br /&gt;
    &lt;br /&gt;
    In r21879, when we converted to using KRB5_CONF macros for profile&lt;br /&gt;
    variable names, we made a typo in krb5_get_tgs_ktypes and erroneously&lt;br /&gt;
    started using default_tkt_enctypes instead of default_tgs_enctypes for&lt;br /&gt;
    TGS requests.  Fix the typo and return to the documented behavior.&lt;br /&gt;
    &lt;br /&gt;
    ticket: 7155&lt;br /&gt;
    target_version: 1.10-next&lt;br /&gt;
    tags: pullup&lt;br /&gt;
&lt;br /&gt;
A ticket can multiple target_version values. If a fix needs to go into multiple releases, use a separate target_version header for each one.&lt;br /&gt;
&lt;br /&gt;
=== New tickets ===&lt;br /&gt;
&lt;br /&gt;
If you are creating a new ticket, run &amp;quot;ssh krbdev.mit.edu krb5-rt-id&amp;quot; to reserve a ticket number, and put &amp;quot;ticket: NNNN (new)&amp;quot; in the commit message, substituting the ticket number for NNNN.  The summary line of the commit will be used as the subject of the new ticket; if this is not what you want, you can use a &amp;quot;subject:&amp;quot; RT header to set the ticket subject, or you can change the subject afterwards in RT.&lt;br /&gt;
&lt;br /&gt;
You can automate this process using a [https://raw.github.com/krb5/krbdev-services/master/githooks-client/commit-msg commit-msg hook].  Drop the contents of the hook into .git/hooks/commit-msg and make it executable.  Then you can put just &amp;quot;ticket: new&amp;quot; at the end of a commit message, and the hook will automatically reserve a ticket number and rewrite the header to &amp;quot;ticket: NNNN (new)&amp;quot;.  You should have some form of passwordless login to krbdev.mit.edu set up for this to work transparently.&lt;br /&gt;
&lt;br /&gt;
=== More about RT keywords ===&lt;br /&gt;
&lt;br /&gt;
These are somewhat inconsistent and will need more editing:&lt;br /&gt;
* Additional detail about [[RT keywords]]&lt;br /&gt;
* [[Manipulating RT tickets using commits]]&lt;br /&gt;
&lt;br /&gt;
== Pushing changes from contributors ==&lt;br /&gt;
&lt;br /&gt;
When integrating code changes created by contributors, take note of the following:&lt;br /&gt;
&lt;br /&gt;
* If the change is presented to you as one or more git commits, fetch the commit into your local git repository and then use git cherry-pick to make a copy of the relevant commits onto your master branch (or a topic branch).  Do not use git merge.&lt;br /&gt;
&lt;br /&gt;
* If the change is presented to you as a patch, make a commit from the patch and use the --author flag to git commit to set the commit author field to the author's name and email address.&lt;br /&gt;
&lt;br /&gt;
* Review the changes as well as possible, and make sure they are organized into logical commits as required by our [[Coding_style/Version_control_practices|version control practices]].  Run the C style checker to identify possible style issues.&lt;br /&gt;
&lt;br /&gt;
* Make sure the changes build and pass &amp;quot;make check&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
* Add appropriate RT headers to the commit messages if appropriate.&lt;br /&gt;
&lt;br /&gt;
* If you need to make significant changes to the commit or commit message, you can add a note to the end (before any RT headers) like:&lt;br /&gt;
&lt;br /&gt;
    [ghudson@mit.edu: Stylistic changes, commit message]&lt;/div&gt;</summary>
		<author><name>Ghudson</name></author>	</entry>

	<entry>
		<id>https://k5wiki.kerberos.org/wiki?title=RT_server_configuration&amp;diff=6031</id>
		<title>RT server configuration</title>
		<link rel="alternate" type="text/html" href="https://k5wiki.kerberos.org/wiki?title=RT_server_configuration&amp;diff=6031"/>
				<updated>2022-04-13T17:13:51Z</updated>
		
		<summary type="html">&lt;p&gt;Ghudson: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page contains notes on the setup of the MIT krb5 RT server. The current server is krbdev.mit.edu (canonical name kerborg-prod-app-1.mit.edu), which runs Ubuntu 20.04.&lt;br /&gt;
&lt;br /&gt;
==Packages==&lt;br /&gt;
&lt;br /&gt;
In Ubuntu 20.04, the request-tracker4 package contains a suitable version of RT.  This package will ask some questions at installation time:&lt;br /&gt;
&lt;br /&gt;
* RT site name: krbdev.mit.edu&lt;br /&gt;
* handle RT_SiteConfig.pm permissions: yes&lt;br /&gt;
* use dbconfig-common: no&lt;br /&gt;
&lt;br /&gt;
The data in RT is stored in a PostgreSQL database.  The postgresql Ubuntu package will install the recommended version of PostgreSQL for the current Ubuntu version.&lt;br /&gt;
&lt;br /&gt;
The mail interface to RT is handled by Postfix, so the postfix package is required.  The libsendmail-pmilter-perl package is required for the custom milter script.&lt;br /&gt;
&lt;br /&gt;
The web front end to RT is an Apache2 web server, so the apache2 package is required.  RT uses a FastCGI server, so the libapache2-mod-fcgid package is required.&lt;br /&gt;
&lt;br /&gt;
The server host acts as an authoritative name server for the kerberos.org zone, so the bind9 package must be installed.&lt;br /&gt;
&lt;br /&gt;
The server hosts the authoritative git repository, so the git package must be installed.&lt;br /&gt;
&lt;br /&gt;
In sum, the following packages must be installed on the RT server:&lt;br /&gt;
&lt;br /&gt;
  apache2&lt;br /&gt;
  bind9&lt;br /&gt;
  git&lt;br /&gt;
  libapache2-mod-fcgid&lt;br /&gt;
  libsendmail-pmilter-perl&lt;br /&gt;
  perl&lt;br /&gt;
  perl-base&lt;br /&gt;
  postfix&lt;br /&gt;
  postgresql&lt;br /&gt;
  request-tracker4&lt;br /&gt;
&lt;br /&gt;
==User accounts==&lt;br /&gt;
&lt;br /&gt;
The postgresql package will create a postgres user account.&lt;br /&gt;
&lt;br /&gt;
The following user accounts and group entries must be created manually:&lt;br /&gt;
&lt;br /&gt;
* group rt&lt;br /&gt;
* user rtcvs: primary group rt, homedir /var/rt2, shell /bin/sh&lt;br /&gt;
* user rt: primary group rt, homedir /var/rt2, shell /bin/false&lt;br /&gt;
&lt;br /&gt;
These accounts could be created with:&lt;br /&gt;
&lt;br /&gt;
  groupadd -r rt&lt;br /&gt;
  useradd -r -g rt -d /var/rt2 rtcvs&lt;br /&gt;
  useradd -r -m -g rt -d /var/rt2 -s /bin/false rt&lt;br /&gt;
&lt;br /&gt;
Some of the above accounts may be created by ops during provisioning.  /var/rt2 and /var/rt2/.ssh must be owned by rtcvs or sshd will reject logins as rtcvs.&lt;br /&gt;
&lt;br /&gt;
For the authoritative repository, create a group named &amp;quot;krbwrite&amp;quot; and an account for each committer, with a root-owned home directory and git-shell configuration:&lt;br /&gt;
&lt;br /&gt;
    groupadd krbwrite&lt;br /&gt;
    # Repeat the following commands for each committer.&lt;br /&gt;
    useradd -u 3622 -s /usr/bin/git-shell -G krbwrite ghudson&lt;br /&gt;
    mkdir /home/ghudson&lt;br /&gt;
    mkdir /home/ghudson/git-shell-commands&lt;br /&gt;
    ln -s /git/krb5.git/hooks/krb5-rt-id /home/ghudson/git-shell-commands&lt;br /&gt;
&lt;br /&gt;
Create /var/rt2/bin and copy in the following scripts from the krbdev-services repository:&lt;br /&gt;
&lt;br /&gt;
  rt-scripts/rt-reserve-ticket&lt;br /&gt;
  rt-scripts/rtmilter.pl&lt;br /&gt;
  rt-scripts/krb5-daily.sh&lt;br /&gt;
  rt-cvs/rt-cvsgate&lt;br /&gt;
&lt;br /&gt;
The scripts and directory should be mode 755 and owned by user rt and group rt.&lt;br /&gt;
&lt;br /&gt;
/var/rt2 should contain an empty .k5login file, managed by ops.  It should contain a .ssh/authorized_keys file, managed by ops, containing the krbsnap key from hooks/krbsnap_rsa_key.pub in the authoritative repository.&lt;br /&gt;
&lt;br /&gt;
Create /var/psqlbackups (owned by root).&lt;br /&gt;
&lt;br /&gt;
The rt user account is not actually needed for the current RT installation, and the homedir name /var/rt2 is outdated.  The following references need to be taken into account when changing the user and group configuration:&lt;br /&gt;
&lt;br /&gt;
* Both the rt and rtcvs accounts have the homedir /var/rt2.&lt;br /&gt;
* krb5-daily.sh references the krbsnap.keytab file and dumps directory in /var/rt2.&lt;br /&gt;
* A root cron job runs krb5-daily.sh from /var/rt2.&lt;br /&gt;
* A root cron job runs rtmilter on boot from /var/rt2.&lt;br /&gt;
* The empty /var/rt2/.k5login file is managed by ops.&lt;br /&gt;
* The /var/rt2/.ssh/authorized_keys file is managed by ops.&lt;br /&gt;
* The authoritative krb5 git repository rt-ssh-cmd config value references the rtcvs user and /var/rt2/bin/rt-cvsgate.&lt;br /&gt;
* The authoritative krb5 git repository hooks/krb5-rt-id script references the rtcvs user and /var/rt2/bin/rt-reserve-ticket.  This script comes from the krbdev-services repository's githooks/krb5-rt-id.&lt;br /&gt;
* Some of the same references are present in the krbdev-services repository, but they aren't used.&lt;br /&gt;
&lt;br /&gt;
==RT setup==&lt;br /&gt;
&lt;br /&gt;
Install the RT_SiteConfig.pm file from the krbdev-services repository in /etc/request-tracker4.&lt;br /&gt;
&lt;br /&gt;
In root's crontab file (&amp;quot;crontab -e&amp;quot; as root), add the following to perform daily maintenance:&lt;br /&gt;
&lt;br /&gt;
  MAILTO=krbcore-hw@mit.edu&lt;br /&gt;
  0 3 * * * /usr/sbin/rt-clean-sessions&lt;br /&gt;
  0 4 * * * /var/rt2/bin/krb5-daily.sh&lt;br /&gt;
&lt;br /&gt;
==PostgreSQL configuration==&lt;br /&gt;
&lt;br /&gt;
Many PostgreSQL files live in directories specific to the PostgreSQL major and minor version, such as /etc/postgresql/8.3 for PostgreSQL 8.3.&lt;br /&gt;
&lt;br /&gt;
The Ubuntu postgresql package will create a &amp;quot;main&amp;quot; cluster with a configuration directory in /etc/postgresql/&amp;lt;version&amp;gt;/main.&lt;br /&gt;
&lt;br /&gt;
In /etc/postgresql/&amp;lt;version&amp;gt;/main/pg_ident.conf, add:&lt;br /&gt;
&lt;br /&gt;
  local		root		root&lt;br /&gt;
  local		root		postgres&lt;br /&gt;
  local		root		rt_user&lt;br /&gt;
  local		rt		rt_user&lt;br /&gt;
  local		rtcvs		rt_user&lt;br /&gt;
  local		postfix		rt_user&lt;br /&gt;
  local		nobody		rt_user&lt;br /&gt;
  local         www-data        rt_user&lt;br /&gt;
&lt;br /&gt;
(The entry for &amp;quot;rt&amp;quot; should no longer be needed, but is currently still present.)&lt;br /&gt;
&lt;br /&gt;
In /etc/postgresql/&amp;lt;version&amp;gt;/main/pg_hba.conf, find the line that reads &amp;quot;local all all peer&amp;quot; and add &amp;quot;map=local&amp;quot; to the end, so it reads &amp;quot;local all all peer map=local&amp;quot;.  Comment out the line that reads &amp;quot;local all postgres peer&amp;quot;, despite the warning not to disable it.  Run &amp;quot;service postgresql restart&amp;quot; to reread the affected files.  Run &amp;quot;psql -Upostgres --list&amp;quot; to verify that the identity map works.&lt;br /&gt;
&lt;br /&gt;
Run &amp;quot;createuser -Upostgres rt_user&amp;quot; to create the rt_user role.&lt;br /&gt;
&lt;br /&gt;
Run &amp;quot;/usr/sbin/rt-setup-database --action create&amp;quot; to create the database, then restore it from a backup with &amp;quot;zcat /path/to/dump.gz | psql -d rt4 -Upostgres&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==Postfix configuration==&lt;br /&gt;
&lt;br /&gt;
By default ops manages Postfix with Puppet.  This must be disabled by ops, and the Debian defaults restored by copying /usr/share/postfix/main.cf.debian to /etc/postfix/main.cf and /usr/share/postfix/master.cf.dist to /etc/postfix/master.cf.&lt;br /&gt;
&lt;br /&gt;
At the end of /etc/postfix/main.cf add:&lt;br /&gt;
&lt;br /&gt;
  myhostname = krbdev.mit.edu&lt;br /&gt;
  mydestination = krbdev.mit.edu, kerborg-prod-app-1.mit.edu, localhost.mit.edu, localhost&lt;br /&gt;
  &lt;br /&gt;
  # Suppress some headers to avoid leaking internal addresses to spammers.&lt;br /&gt;
  prepend_delivered_header =&lt;br /&gt;
  enable_original_recipient = no&lt;br /&gt;
  &lt;br /&gt;
  # RT header milter&lt;br /&gt;
  smtpd_milters = unix:private/milter&lt;br /&gt;
&lt;br /&gt;
Copy /etc/aliases from the old server.  To avoid aiding spammers, its contents are not reproduced here.  In particular, /etc/aliases contains an internal address corresponding to the membership of the krb5-bugs-incoming mailman list; revealing this address could allow spammers to bypass moderation of incoming bug reports.&lt;br /&gt;
&lt;br /&gt;
In root's crontab file (&amp;quot;crontab -e&amp;quot; as root):&lt;br /&gt;
&lt;br /&gt;
  @reboot /var/rt2/bin/rtmilter.pl /var/spool/postfix/private/milter&lt;br /&gt;
&lt;br /&gt;
Run the command by hand (backgrounded) to start the milter process before the next reboot.&lt;br /&gt;
&lt;br /&gt;
Run &amp;quot;newaliases&amp;quot; and &amp;quot;postfix reload&amp;quot; to pick up the changed configuration.&lt;br /&gt;
&lt;br /&gt;
Make sure rt@kerborg-prod-app-1.mit.edu and rt-comment@kerborg-prod-app-1.mit.edu are authorized as non-member senders at https://mailman.mit.edu:444/mailman/admin/krb5-bugs/privacy/sender .&lt;br /&gt;
&lt;br /&gt;
==Apache httpd configuration==&lt;br /&gt;
&lt;br /&gt;
Create /etc/apache2/ssl.crt and /etc/apache2/ssl.key.&lt;br /&gt;
&lt;br /&gt;
Copy /etc/apache2/ssl.key/server.key and /etc/apache2/ssl.crt/server.crt from the old server, or follow the instructions at http://kb.mit.edu/confluence/display/istcontrib/Obtaining+an+SSL+certificate+for+a+web+server to obtain a new one.  server.key and server.crt may be symlinks using whatever scheme seems convenient for renewing certificates every few years.&lt;br /&gt;
&lt;br /&gt;
Install /etc/apache2/ssl.crt/chain.crt from /mit/apache-ssl/certificates/InCommon-chain.crt.txt (requires tokens).  Cutting and pasting is effective for transferring certificates as they are represented as short text files.&lt;br /&gt;
&lt;br /&gt;
Install /etc/apache2/ssl.crt/clientCA.crt from /mit/apache-ssl/certificates/mitCAclient.pem (requires tokens).&lt;br /&gt;
&lt;br /&gt;
Install the rt.conf file from the krbdev-services repository as /etc/apache2/sites-available/rt.conf .&lt;br /&gt;
&lt;br /&gt;
Edit /etc/apache2/mods-available/proxy.conf and set:&lt;br /&gt;
&lt;br /&gt;
  ProxyVia On&lt;br /&gt;
&lt;br /&gt;
  ProxyPass /buildbot/ws ws://krbdev-buildbot.mit.edu:8010/ws&lt;br /&gt;
  ProxyPassReverse /buildbos/ws ws://krbdev-buildbot.mit.edu:8010/ws&lt;br /&gt;
  ProxyPass /buildbot/ http://krbdev-buildbot.mit.edu:8010/&lt;br /&gt;
  ProxyPassReverse /buildbot/ http://krbdev-buildbot.mit.edu:8010/&lt;br /&gt;
  &amp;lt;Proxy http://krbdev-buildbot.mit.edu:8010/*&amp;gt;&lt;br /&gt;
          Allow from all&lt;br /&gt;
  &amp;lt;/Proxy&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Edit /etc/apache2/ports.conf and add &amp;quot;Listen 444&amp;quot; in the ssl_module section after &amp;quot;Listen 443&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Clean out /var/www and install index.html and robots.txt from the krbdev-www directory of the krbdev-services repository.&lt;br /&gt;
&lt;br /&gt;
Run:&lt;br /&gt;
&lt;br /&gt;
  a2enmod ssl&lt;br /&gt;
  a2enmod userdir&lt;br /&gt;
  a2enmod rewrite&lt;br /&gt;
  a2enmod proxy_http&lt;br /&gt;
  a2enmod proxy_wstunnel&lt;br /&gt;
  a2dissite 000-default&lt;br /&gt;
  a2ensite rt&lt;br /&gt;
  service apache2 restart&lt;br /&gt;
&lt;br /&gt;
==Testing==&lt;br /&gt;
&lt;br /&gt;
Get a certificate for the new VM's real hostname and temporarily point /etc/apache2/ssl.crt/server.crt at it.&lt;br /&gt;
&lt;br /&gt;
In /etc/request-tracker4/RT_SiteConfig.pm, temporarily set @ReferrerWhitelist to use the real hostname instead of krbdev.mit.edu.&lt;br /&gt;
&lt;br /&gt;
Temporarily set emergency moderation on the krb5-bugs mailing list (at https://mailman.mit.edu:444/mailman/admin/krb5-bugs/general ) to ensure that mail sent to that list as the result of testing is caught in the moderation queue.&lt;br /&gt;
&lt;br /&gt;
Verify that RT displays at https://realhostname/rt and tickets can be accessed.  Verify that https://realhostname:444/ works and that a new ticket can be created.  Respond to the ticket via email and verify that the response is stored in the ticket.&lt;br /&gt;
&lt;br /&gt;
As root, run /var/rt2/bin/krb5-daily.sh and verify that a dump file appears in /var/psqlbackups.&lt;br /&gt;
&lt;br /&gt;
As rtcvs (&amp;quot;su -s /bin/bash - rtcvs&amp;quot;), run /var/rt2/bin/rt-reserve-ticket and verify that a ticket number is printed.&lt;br /&gt;
&lt;br /&gt;
To test rt-cvsgate, create a test message in /tmp/testmsg like so:&lt;br /&gt;
&lt;br /&gt;
  ticket: new&lt;br /&gt;
  id: NNNN (use the ticket number printed by rt-reserve-ticket above)&lt;br /&gt;
  subject: rt-cvsgate test&lt;br /&gt;
  tags: pullup&lt;br /&gt;
&lt;br /&gt;
  test commit message&lt;br /&gt;
&lt;br /&gt;
As rtcvs, run &amp;quot;/var/rt2/bin/rt-cvsgate ''username'' &amp;lt; /tmp/testmsg&amp;quot;, where ''username'' is an authorized user.&lt;br /&gt;
&lt;br /&gt;
Undo the temporary changes and restore the database from a dump file.&lt;br /&gt;
&lt;br /&gt;
==BIND configuration==&lt;br /&gt;
&lt;br /&gt;
The bind9 configuration files can be found in krbdev-services under bind. They should be installed under /etc/bind. &amp;quot;rndc reload&amp;quot; will restart the runing named with the changed configuration. If it is necessary to edit any of the zone files, be sure to update the serial number in the SOA record to the current date followed by &amp;quot;00&amp;quot; (or &amp;quot;01&amp;quot; etc. for successive edits in the same day).&lt;br /&gt;
&lt;br /&gt;
If the IP address if kerberos.org needs to be changed, the glue record at hover.com must be updated. In the current Hover UI, glue records can be found under &amp;quot;advanced&amp;quot;. The transfer lock on the domain must be temporarily disabled (via the Overview screen) to update glue records.&lt;br /&gt;
&lt;br /&gt;
==Git repository==&lt;br /&gt;
&lt;br /&gt;
The authoritative krb5 git repository lives in /git/krb5.git.  If this repository needs to be reconstructed from another mirror of the repository, install the hooks from the githooks directory of krbdev-services, add the krbsnap private and public SSH key to the hooks directory, and run the git configuration commands from gitconvert/krb5-convert.sh in krbdev-services.&lt;br /&gt;
&lt;br /&gt;
The authoritative krbdev-services repository lives in /git/krbdev-services.git.&lt;/div&gt;</summary>
		<author><name>Ghudson</name></author>	</entry>

	<entry>
		<id>https://k5wiki.kerberos.org/wiki?title=RT_server_configuration&amp;diff=6030</id>
		<title>RT server configuration</title>
		<link rel="alternate" type="text/html" href="https://k5wiki.kerberos.org/wiki?title=RT_server_configuration&amp;diff=6030"/>
				<updated>2022-04-13T06:01:07Z</updated>
		
		<summary type="html">&lt;p&gt;Ghudson: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page contains notes on the setup of the MIT krb5 RT server. The current server is krbdev.mit.edu (canonical name kerborg-prod-app-1.mit.edu), which runs Ubuntu 20.04.&lt;br /&gt;
&lt;br /&gt;
==Packages==&lt;br /&gt;
&lt;br /&gt;
In Ubuntu 20.04, the request-tracker4 package contains a suitable version of RT.  This package will ask some questions at installation time:&lt;br /&gt;
&lt;br /&gt;
* RT site name: krbdev.mit.edu&lt;br /&gt;
* handle RT_SiteConfig.pm permissions: yes&lt;br /&gt;
* use dbconfig-common: no&lt;br /&gt;
&lt;br /&gt;
The data in RT is stored in a PostgreSQL database.  The postgresql Ubuntu package will install the recommended version of PostgreSQL for the current Ubuntu version.&lt;br /&gt;
&lt;br /&gt;
The mail interface to RT is handled by Postfix, so the postfix package is required.  The libsendmail-pmilter-perl package is required for the custom milter script.&lt;br /&gt;
&lt;br /&gt;
The web front end to RT is an Apache2 web server, so the apache2 package is required.  RT uses a FastCGI server, so the libapache2-mod-fcgid package is required.&lt;br /&gt;
&lt;br /&gt;
The server host acts as an authoritative name server for the kerberos.org zone, so the bind9 package must be installed.&lt;br /&gt;
&lt;br /&gt;
The server hosts the authoritative git repository, so the git package must be installed.&lt;br /&gt;
&lt;br /&gt;
In sum, the following packages must be installed on the RT server:&lt;br /&gt;
&lt;br /&gt;
  apache2&lt;br /&gt;
  bind9&lt;br /&gt;
  git&lt;br /&gt;
  libapache2-mod-fcgid&lt;br /&gt;
  libsendmail-pmilter-perl&lt;br /&gt;
  perl&lt;br /&gt;
  perl-base&lt;br /&gt;
  postfix&lt;br /&gt;
  postgresql&lt;br /&gt;
  request-tracker4&lt;br /&gt;
&lt;br /&gt;
==User accounts==&lt;br /&gt;
&lt;br /&gt;
The postgresql package will create a postgres user account.&lt;br /&gt;
&lt;br /&gt;
The following user accounts and group entries must be created manually:&lt;br /&gt;
&lt;br /&gt;
* group rt&lt;br /&gt;
* user rtcvs: primary group rt, homedir /var/rt2, shell /bin/sh&lt;br /&gt;
* user rt: primary group rt, homedir /var/rt2, shell /bin/false&lt;br /&gt;
&lt;br /&gt;
These accounts could be created with:&lt;br /&gt;
&lt;br /&gt;
  groupadd -r rt&lt;br /&gt;
  useradd -r -g rt -d /var/rt2 rtcvs&lt;br /&gt;
  useradd -r -m -g rt -d /var/rt2 -s /bin/false rt&lt;br /&gt;
&lt;br /&gt;
Some of the above accounts may be created by ops during provisioning.  /var/rt2 and /var/rt2/.ssh must be owned by rtcvs or sshd will reject logins as rtcvs.&lt;br /&gt;
&lt;br /&gt;
For the authoritative repository, create a group named &amp;quot;krbwrite&amp;quot; and an account for each committer, with a root-owned home directory and git-shell configuration:&lt;br /&gt;
&lt;br /&gt;
    groupadd krbwrite&lt;br /&gt;
    # Repeat the following commands for each committer.&lt;br /&gt;
    useradd -u 3622 -s /usr/bin/git-shell -G krbwrite ghudson&lt;br /&gt;
    mkdir /home/ghudson&lt;br /&gt;
    mkdir /home/ghudson/git-shell-commands&lt;br /&gt;
    ln -s /git/krb5.git/hooks/krb5-rt-id /home/ghudson/git-shell-commands&lt;br /&gt;
&lt;br /&gt;
Create /var/rt2/bin and copy in the following scripts from the krbdev-services repository:&lt;br /&gt;
&lt;br /&gt;
  rt-scripts/rt-reserve-ticket&lt;br /&gt;
  rt-scripts/rtmilter.pl&lt;br /&gt;
  rt-scripts/krb5-daily.sh&lt;br /&gt;
  rt-cvs/rt-cvsgate&lt;br /&gt;
&lt;br /&gt;
The scripts and directory should be mode 755 and owned by user rt and group rt.&lt;br /&gt;
&lt;br /&gt;
/var/rt2 should contain an empty .k5login file, managed by ops.  It should contain a .ssh/authorized_keys file, managed by ops, containing the krbsnap key from hooks/krbsnap_rsa_key.pub in the authoritative repository.&lt;br /&gt;
&lt;br /&gt;
Create /var/psqlbackups (owned by root).&lt;br /&gt;
&lt;br /&gt;
The rt user account is not actually needed for the current RT installation, and the homedir name /var/rt2 is outdated.  The following references need to be taken into account when changing the user and group configuration:&lt;br /&gt;
&lt;br /&gt;
* Both the rt and rtcvs accounts have the homedir /var/rt2.&lt;br /&gt;
* krb5-daily.sh references the krbsnap.keytab file and dumps directory in /var/rt2.&lt;br /&gt;
* A root cron job runs krb5-daily.sh from /var/rt2.&lt;br /&gt;
* A root cron job runs rtmilter on boot from /var/rt2.&lt;br /&gt;
* The empty /var/rt2/.k5login file is managed by ops.&lt;br /&gt;
* The /var/rt2/.ssh/authorized_keys file is managed by ops.&lt;br /&gt;
* The authoritative krb5 git repository rt-ssh-cmd config value references the rtcvs user and /var/rt2/bin/rt-cvsgate.&lt;br /&gt;
* The authoritative krb5 git repository hooks/krb5-rt-id script references the rtcvs user and /var/rt2/bin/rt-reserve-ticket.  This script comes from the krbdev-services repository's githooks/krb5-rt-id.&lt;br /&gt;
* Some of the same references are present in the krbdev-services repository, but they aren't used.&lt;br /&gt;
&lt;br /&gt;
==RT setup==&lt;br /&gt;
&lt;br /&gt;
Install the RT_SiteConfig.pm file from the krbdev-services repository in /etc/request-tracker4.&lt;br /&gt;
&lt;br /&gt;
In root's crontab file (&amp;quot;crontab -e&amp;quot; as root), add the following to perform daily maintenance:&lt;br /&gt;
&lt;br /&gt;
  MAILTO=krbcore-hw@mit.edu&lt;br /&gt;
  0 3 * * * /usr/sbin/rt-clean-sessions&lt;br /&gt;
  0 4 * * * /var/rt2/bin/krb5-daily.sh&lt;br /&gt;
&lt;br /&gt;
==PostgreSQL configuration==&lt;br /&gt;
&lt;br /&gt;
Many PostgreSQL files live in directories specific to the PostgreSQL major and minor version, such as /etc/postgresql/8.3 for PostgreSQL 8.3.&lt;br /&gt;
&lt;br /&gt;
The Ubuntu postgresql package will create a &amp;quot;main&amp;quot; cluster with a configuration directory in /etc/postgresql/&amp;lt;version&amp;gt;/main.&lt;br /&gt;
&lt;br /&gt;
In /etc/postgresql/&amp;lt;version&amp;gt;/main/pg_ident.conf, add:&lt;br /&gt;
&lt;br /&gt;
  local		root		root&lt;br /&gt;
  local		root		postgres&lt;br /&gt;
  local		root		rt_user&lt;br /&gt;
  local		rt		rt_user&lt;br /&gt;
  local		rtcvs		rt_user&lt;br /&gt;
  local		postfix		rt_user&lt;br /&gt;
  local		nobody		rt_user&lt;br /&gt;
  local         www-data        rt_user&lt;br /&gt;
&lt;br /&gt;
(The entry for &amp;quot;rt&amp;quot; should no longer be needed, but is currently still present.)&lt;br /&gt;
&lt;br /&gt;
In /etc/postgresql/&amp;lt;version&amp;gt;/main/pg_hba.conf, find the line that reads &amp;quot;local all all peer&amp;quot; and add &amp;quot;map=local&amp;quot; to the end, so it reads &amp;quot;local all all peer map=local&amp;quot;.  Comment out the line that reads &amp;quot;local all postgres peer&amp;quot;, despite the warning not to disable it.  Run &amp;quot;service postgresql restart&amp;quot; to reread the affected files.  Run &amp;quot;psql -Upostgres --list&amp;quot; to verify that the identity map works.&lt;br /&gt;
&lt;br /&gt;
Run &amp;quot;createuser -Upostgres rt_user&amp;quot; to create the rt_user role.&lt;br /&gt;
&lt;br /&gt;
Run &amp;quot;/usr/sbin/rt-setup-database --action create&amp;quot; to create the database, then restore it from a backup with &amp;quot;zcat /path/to/dump.gz | psql -d rt4 -Upostgres&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==Postfix configuration==&lt;br /&gt;
&lt;br /&gt;
By default ops manages Postfix with Puppet.  This must be disabled by ops, and the Debian defaults restored by copying /usr/share/postfix/main.cf.debian to /etc/postfix/main.cf and /usr/share/postfix/master.cf.dist to /etc/postfix/master.cf.&lt;br /&gt;
&lt;br /&gt;
At the end of /etc/postfix/main.cf add:&lt;br /&gt;
&lt;br /&gt;
  myhostname = krbdev.mit.edu&lt;br /&gt;
  mydestination = krbdev.mit.edu, kerborg-prod-app-1.mit.edu, localhost.mit.edu, localhost&lt;br /&gt;
  &lt;br /&gt;
  # Suppress some headers to avoid leaking internal addresses to spammers.&lt;br /&gt;
  prepend_delivered_header =&lt;br /&gt;
  enable_original_recipient = no&lt;br /&gt;
  &lt;br /&gt;
  # RT header milter&lt;br /&gt;
  smtpd_milters = unix:private/milter&lt;br /&gt;
&lt;br /&gt;
Copy /etc/aliases from the old server.  To avoid aiding spammers, its contents are not reproduced here.  In particular, /etc/aliases contains an internal address corresponding to the membership of the krb5-bugs-incoming mailman list; revealing this address could allow spammers to bypass moderation of incoming bug reports.&lt;br /&gt;
&lt;br /&gt;
In root's crontab file (&amp;quot;crontab -e&amp;quot; as root):&lt;br /&gt;
&lt;br /&gt;
  @reboot /var/rt2/bin/rtmilter.pl /var/spool/postfix/private/milter&lt;br /&gt;
&lt;br /&gt;
Run the command by hand (backgrounded) to start the milter process before the next reboot.&lt;br /&gt;
&lt;br /&gt;
Run &amp;quot;newaliases&amp;quot; and &amp;quot;postfix reload&amp;quot; to pick up the changed configuration.&lt;br /&gt;
&lt;br /&gt;
Make sure rt@kerborg-prod-app-1.mit.edu and rt-comment@kerborg-prod-app-1.mit.edu are authorized as non-member senders at https://mailman.mit.edu:444/mailman/admin/krb5-bugs/privacy/sender .&lt;br /&gt;
&lt;br /&gt;
==Apache httpd configuration==&lt;br /&gt;
&lt;br /&gt;
Create /etc/apache2/ssl.crt and /etc/apache2/ssl.key.&lt;br /&gt;
&lt;br /&gt;
Copy /etc/apache2/ssl.key/server.key and /etc/apache2/ssl.crt/server.crt from the old server, or follow the instructions at http://kb.mit.edu/confluence/display/istcontrib/Obtaining+an+SSL+certificate+for+a+web+server to obtain a new one.  server.key and server.crt may be symlinks using whatever scheme seems convenient for renewing certificates every few years.&lt;br /&gt;
&lt;br /&gt;
Install /etc/apache2/ssl.crt/chain.crt from /mit/apache-ssl/certificates/InCommon-chain.crt.txt (requires tokens).  Cutting and pasting is effective for transferring certificates as they are represented as short text files.&lt;br /&gt;
&lt;br /&gt;
Install /etc/apache2/ssl.crt/clientCA.crt from /mit/apache-ssl/certificates/mitCAclient.pem (requires tokens).&lt;br /&gt;
&lt;br /&gt;
Install the rt.conf file from the krbdev-services repository as /etc/apache2/sites-available/rt.conf .&lt;br /&gt;
&lt;br /&gt;
Edit /etc/apache2/mods-available/proxy.conf and set:&lt;br /&gt;
&lt;br /&gt;
  ProxyVia On&lt;br /&gt;
&lt;br /&gt;
  ProxyPass /buildbot/ws ws://krbdev-buildbot.mit.edu:8010/ws&lt;br /&gt;
  ProxyPassReverse /buildbos/ws ws://krbdev-buildbot.mit.edu:8010/ws&lt;br /&gt;
  ProxyPass /buildbot/ http://krbdev-buildbot.mit.edu:8010/&lt;br /&gt;
  ProxyPassReverse /buildbot/ http://krbdev-buildbot.mit.edu:8010/&lt;br /&gt;
  &amp;lt;Proxy http://krbdev-buildbot.mit.edu:8010/*&amp;gt;&lt;br /&gt;
          Allow from all&lt;br /&gt;
  &amp;lt;/Proxy&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Edit /etc/apache2/ports.conf and add &amp;quot;Listen 444&amp;quot; in the ssl_module section after &amp;quot;Listen 443&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Clean out /var/www and install index.html and robots.txt from the krbdev-www directory of the krbdev-services repository.&lt;br /&gt;
&lt;br /&gt;
Run:&lt;br /&gt;
&lt;br /&gt;
  a2enmod ssl&lt;br /&gt;
  a2enmod userdir&lt;br /&gt;
  a2enmod rewrite&lt;br /&gt;
  a2enmod proxy_http&lt;br /&gt;
  a2enmod proxy_wstunnel&lt;br /&gt;
  a2dissite 000-default&lt;br /&gt;
  a2ensite rt&lt;br /&gt;
  service apache2 restart&lt;br /&gt;
&lt;br /&gt;
==Testing==&lt;br /&gt;
&lt;br /&gt;
Get a certificate for the new VM's real hostname and temporarily point /etc/apache2/ssl.crt/server.crt at it.&lt;br /&gt;
&lt;br /&gt;
In /etc/request-tracker4/RT_SiteConfig.pm, temporarily set @ReferrerWhitelist to use the real hostname instead of krbdev.mit.edu.&lt;br /&gt;
&lt;br /&gt;
Temporarily set emergency moderation on the krb5-bugs mailing list (at https://mailman.mit.edu:444/mailman/admin/krb5-bugs/general ) to ensure that mail sent to that list as the result of testing is caught in the moderation queue.&lt;br /&gt;
&lt;br /&gt;
Verify that RT displays at https://realhostname/rt and tickets can be accessed.  Verify that https://realhostname:444/ works and that a new ticket can be created.  Respond to the ticket via email and verify that the response is stored in the ticket.&lt;br /&gt;
&lt;br /&gt;
As root, run /var/rt2/bin/krb5-daily.sh and verify that a dump file appears in /var/psqlbackups.&lt;br /&gt;
&lt;br /&gt;
As rtcvs (&amp;quot;su -s /bin/bash - rtcvs&amp;quot;), run /var/rt2/bin/rt-reserve-ticket and verify that a ticket number is printed.&lt;br /&gt;
&lt;br /&gt;
To test rt-cvsgate, create a test message in /tmp/testmsg like so:&lt;br /&gt;
&lt;br /&gt;
  ticket: new&lt;br /&gt;
  id: NNNN (use the ticket number printed by rt-reserve-ticket above)&lt;br /&gt;
  subject: rt-cvsgate test&lt;br /&gt;
  tags: pullup&lt;br /&gt;
&lt;br /&gt;
  test commit message&lt;br /&gt;
&lt;br /&gt;
As rtcvs, run &amp;quot;/var/rt2/bin/rt-cvsgate ''username'' &amp;lt; /tmp/testmsg&amp;quot;, where ''username'' is an authorized user.&lt;br /&gt;
&lt;br /&gt;
Undo the temporary changes and restore the database from a dump file.&lt;br /&gt;
&lt;br /&gt;
==BIND configuration==&lt;br /&gt;
&lt;br /&gt;
The bind9 configuration files can be found in krbdev-services under bind. They should be installed under /etc/bind. &amp;quot;rndc reload&amp;quot; will restart the runing named with the changed configuration. If it is necessary to edit any of the zone files, be sure to update the serial number in the SOA record to the current date followed by &amp;quot;00&amp;quot; (or &amp;quot;01&amp;quot; etc. for successive edits in the same day).&lt;br /&gt;
&lt;br /&gt;
If the IP address if kerberos.org needs to be changed, the glue record at hover.com must be updated. In the current Hover UI, glue records can be found under &amp;quot;advanced&amp;quot;. The transfer lock on the domain must be temporarily disabled (via the Overview screen) to update glue records.&lt;br /&gt;
&lt;br /&gt;
==Git repository==&lt;br /&gt;
&lt;br /&gt;
The authoritative git repository lives in /git/krb5.git.  If this repository needs to be reconstructed from another mirror of the repository, install the hooks from the githooks directory of krbdev-services, add the krbsnap private and public SSH key to the hooks directory, and run the git configuration commands from gitconvert/krb5-convert.sh in krbdev-services.&lt;/div&gt;</summary>
		<author><name>Ghudson</name></author>	</entry>

	<entry>
		<id>https://k5wiki.kerberos.org/wiki?title=RT_server_configuration&amp;diff=6029</id>
		<title>RT server configuration</title>
		<link rel="alternate" type="text/html" href="https://k5wiki.kerberos.org/wiki?title=RT_server_configuration&amp;diff=6029"/>
				<updated>2022-04-12T23:20:18Z</updated>
		
		<summary type="html">&lt;p&gt;Ghudson: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page contains notes on the setup of the MIT krb5 RT server. The current server is krbdev.mit.edu (canonical name kerborg-prod-app-1.mit.edu), which runs Ubuntu 20.04.&lt;br /&gt;
&lt;br /&gt;
==Packages==&lt;br /&gt;
&lt;br /&gt;
In Ubuntu 20.04, the request-tracker4 package contains a suitable version of RT.  This package will ask some questions at installation time:&lt;br /&gt;
&lt;br /&gt;
* RT site name: krbdev.mit.edu&lt;br /&gt;
* handle RT_SiteConfig.pm permissions: yes&lt;br /&gt;
* use dbconfig-common: no&lt;br /&gt;
&lt;br /&gt;
The data in RT is stored in a PostgreSQL database.  The postgresql Ubuntu package will install the recommended version of PostgreSQL for the current Ubuntu version.&lt;br /&gt;
&lt;br /&gt;
The mail interface to RT is handled by Postfix, so the postfix package is required.  The libsendmail-pmilter-perl package is required for the custom milter script.&lt;br /&gt;
&lt;br /&gt;
The web front end to RT is an Apache2 web server, so the apache2 package is required.  RT uses a FastCGI server, so the libapache2-mod-fcgid package is required.&lt;br /&gt;
&lt;br /&gt;
The server host acts as an authoritative name server for the kerberos.org zone, so the bind9 package must be installed.&lt;br /&gt;
&lt;br /&gt;
In sum, the following packages must be installed on the RT server:&lt;br /&gt;
&lt;br /&gt;
  apache2&lt;br /&gt;
  bind9&lt;br /&gt;
  libapache2-mod-fcgid&lt;br /&gt;
  libsendmail-pmilter-perl&lt;br /&gt;
  perl&lt;br /&gt;
  perl-base&lt;br /&gt;
  postfix&lt;br /&gt;
  postgresql&lt;br /&gt;
  request-tracker4&lt;br /&gt;
&lt;br /&gt;
==User accounts==&lt;br /&gt;
&lt;br /&gt;
The postgresql package will create a postgres user account.&lt;br /&gt;
&lt;br /&gt;
The following user accounts and group entries must be created manually:&lt;br /&gt;
&lt;br /&gt;
* group rt&lt;br /&gt;
* user rtcvs: primary group rt, homedir /var/rt2, shell /bin/sh&lt;br /&gt;
* user rt: primary group rt, homedir /var/rt2, shell /bin/false&lt;br /&gt;
&lt;br /&gt;
These accounts could be created with:&lt;br /&gt;
&lt;br /&gt;
  groupadd -r rt&lt;br /&gt;
  useradd -r -g rt -d /var/rt2 rtcvs&lt;br /&gt;
  useradd -r -m -g rt -d /var/rt2 -s /bin/false rt&lt;br /&gt;
&lt;br /&gt;
Some of the above accounts may be created by ops during provisioning.  /var/rt2 and /var/rt2/.ssh must be owned by rtcvs or sshd will reject logins as rtcvs.&lt;br /&gt;
&lt;br /&gt;
For the authoritative repository, create a group named &amp;quot;krbwrite&amp;quot; and an account for each committer, with a root-owned home directory and git-shell configuration:&lt;br /&gt;
&lt;br /&gt;
    groupadd krbwrite&lt;br /&gt;
    useradd -u 3622 -s /usr/bin/git-shell -G krbwrite ghudson&lt;br /&gt;
    mkdir /home/ghudson&lt;br /&gt;
    mkdir /home/ghudson/git-shell-commands&lt;br /&gt;
    ln -s /git/krb5.git/hooks/krb5-rt-id /home/ghudson/git-shell-commands&lt;br /&gt;
&lt;br /&gt;
Create /var/rt2/bin and copy in the following scripts from the krbdev-services repository:&lt;br /&gt;
&lt;br /&gt;
  rt-scripts/rt-reserve-ticket&lt;br /&gt;
  rt-scripts/rtmilter.pl&lt;br /&gt;
  rt-scripts/krb5-daily.sh&lt;br /&gt;
  rt-cvs/rt-cvsgate&lt;br /&gt;
&lt;br /&gt;
The scripts and directory should be mode 755 and owned by user rt and group rt.&lt;br /&gt;
&lt;br /&gt;
/var/rt2 should contain an empty .k5login file, managed by ops.  It should contain a .ssh/authorized_keys file, managed by ops, containing the krbsnap key from hooks/krbsnap_rsa_key.pub in the authoritative repository.&lt;br /&gt;
&lt;br /&gt;
Create /var/psqlbackups (owned by root).&lt;br /&gt;
&lt;br /&gt;
The rt user account is not actually needed for the current RT installation, and the homedir name /var/rt2 is outdated.  The following references need to be taken into account when changing the user and group configuration:&lt;br /&gt;
&lt;br /&gt;
* Both the rt and rtcvs accounts have the homedir /var/rt2.&lt;br /&gt;
* krb5-daily.sh references the krbsnap.keytab file and dumps directory in /var/rt2.&lt;br /&gt;
* A root cron job runs krb5-daily.sh from /var/rt2.&lt;br /&gt;
* A root cron job runs rtmilter on boot from /var/rt2.&lt;br /&gt;
* The empty /var/rt2/.k5login file is managed by ops.&lt;br /&gt;
* The /var/rt2/.ssh/authorized_keys file is managed by ops.&lt;br /&gt;
* The authoritative krb5 git repository rt-ssh-cmd config value references the rtcvs user and /var/rt2/bin/rt-cvsgate.&lt;br /&gt;
* The authoritative krb5 git repository hooks/krb5-rt-id script references the rtcvs user and /var/rt2/bin/rt-reserve-ticket.  This script comes from the krbdev-services repository's githooks/krb5-rt-id.&lt;br /&gt;
* Some of the same references are present in the krbdev-services repository, but they aren't used.&lt;br /&gt;
&lt;br /&gt;
==RT setup==&lt;br /&gt;
&lt;br /&gt;
Install the RT_SiteConfig.pm file from the krbdev-services repository in /etc/request-tracker4.&lt;br /&gt;
&lt;br /&gt;
In root's crontab file (&amp;quot;crontab -e&amp;quot; as root), add the following to perform daily maintenance:&lt;br /&gt;
&lt;br /&gt;
  MAILTO=krbcore-hw@mit.edu&lt;br /&gt;
  0 3 * * * /usr/sbin/rt-clean-sessions&lt;br /&gt;
  0 4 * * * /var/rt2/bin/krb5-daily.sh&lt;br /&gt;
&lt;br /&gt;
==PostgreSQL configuration==&lt;br /&gt;
&lt;br /&gt;
Many PostgreSQL files live in directories specific to the PostgreSQL major and minor version, such as /etc/postgresql/8.3 for PostgreSQL 8.3.&lt;br /&gt;
&lt;br /&gt;
The Ubuntu postgresql package will create a &amp;quot;main&amp;quot; cluster with a configuration directory in /etc/postgresql/&amp;lt;version&amp;gt;/main.&lt;br /&gt;
&lt;br /&gt;
In /etc/postgresql/&amp;lt;version&amp;gt;/main/pg_ident.conf, add:&lt;br /&gt;
&lt;br /&gt;
  local		root		root&lt;br /&gt;
  local		root		postgres&lt;br /&gt;
  local		root		rt_user&lt;br /&gt;
  local		rt		rt_user&lt;br /&gt;
  local		rtcvs		rt_user&lt;br /&gt;
  local		postfix		rt_user&lt;br /&gt;
  local		nobody		rt_user&lt;br /&gt;
  local         www-data        rt_user&lt;br /&gt;
&lt;br /&gt;
(The entry for &amp;quot;rt&amp;quot; should no longer be needed, but is currently still present.)&lt;br /&gt;
&lt;br /&gt;
In /etc/postgresql/&amp;lt;version&amp;gt;/main/pg_hba.conf, find the line that reads &amp;quot;local all all peer&amp;quot; and add &amp;quot;map=local&amp;quot; to the end, so it reads &amp;quot;local all all peer map=local&amp;quot;.  Comment out the line that reads &amp;quot;local all postgres peer&amp;quot;, despite the warning not to disable it.  Run &amp;quot;service postgresql restart&amp;quot; to reread the affected files.  Run &amp;quot;psql -Upostgres --list&amp;quot; to verify that the identity map works.&lt;br /&gt;
&lt;br /&gt;
Run &amp;quot;createuser -Upostgres rt_user&amp;quot; to create the rt_user role.&lt;br /&gt;
&lt;br /&gt;
Run &amp;quot;/usr/sbin/rt-setup-database --action create&amp;quot; to create the database, then restore it from a backup with &amp;quot;zcat /path/to/dump.gz | psql -d rt4 -Upostgres&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==Postfix configuration==&lt;br /&gt;
&lt;br /&gt;
By default ops manages Postfix with Puppet.  This must be disabled by ops, and the Debian defaults restored by copying /usr/share/postfix/main.cf.debian to /etc/postfix/main.cf and /usr/share/postfix/master.cf.dist to /etc/postfix/master.cf.&lt;br /&gt;
&lt;br /&gt;
At the end of /etc/postfix/main.cf add:&lt;br /&gt;
&lt;br /&gt;
  myhostname = krbdev.mit.edu&lt;br /&gt;
  mydestination = krbdev.mit.edu, kerborg-prod-app-1.mit.edu, localhost.mit.edu, localhost&lt;br /&gt;
  &lt;br /&gt;
  # Suppress some headers to avoid leaking internal addresses to spammers.&lt;br /&gt;
  prepend_delivered_header =&lt;br /&gt;
  enable_original_recipient = no&lt;br /&gt;
  &lt;br /&gt;
  # RT header milter&lt;br /&gt;
  smtpd_milters = unix:private/milter&lt;br /&gt;
&lt;br /&gt;
Copy /etc/aliases from the old server.  To avoid aiding spammers, its contents are not reproduced here.  In particular, /etc/aliases contains an internal address corresponding to the membership of the krb5-bugs-incoming mailman list; revealing this address could allow spammers to bypass moderation of incoming bug reports.&lt;br /&gt;
&lt;br /&gt;
In root's crontab file (&amp;quot;crontab -e&amp;quot; as root):&lt;br /&gt;
&lt;br /&gt;
  @reboot /var/rt2/bin/rtmilter.pl /var/spool/postfix/private/milter&lt;br /&gt;
&lt;br /&gt;
Run the command by hand (backgrounded) to start the milter process before the next reboot.&lt;br /&gt;
&lt;br /&gt;
Run &amp;quot;newaliases&amp;quot; and &amp;quot;postfix reload&amp;quot; to pick up the changed configuration.&lt;br /&gt;
&lt;br /&gt;
Make sure rt@kerborg-prod-app-1.mit.edu and rt-comment@kerborg-prod-app-1.mit.edu are authorized as non-member senders at https://mailman.mit.edu:444/mailman/admin/krb5-bugs/privacy/sender .&lt;br /&gt;
&lt;br /&gt;
==Apache httpd configuration==&lt;br /&gt;
&lt;br /&gt;
Create /etc/apache2/ssl.crt and /etc/apache2/ssl.key.&lt;br /&gt;
&lt;br /&gt;
Copy /etc/apache2/ssl.key/server.key and /etc/apache2/ssl.crt/server.crt from the old server, or follow the instructions at http://kb.mit.edu/confluence/display/istcontrib/Obtaining+an+SSL+certificate+for+a+web+server to obtain a new one.  server.key and server.crt may be symlinks using whatever scheme seems convenient for renewing certificates every few years.&lt;br /&gt;
&lt;br /&gt;
Install /etc/apache2/ssl.crt/chain.crt from /mit/apache-ssl/certificates/InCommon-chain.crt.txt (requires tokens).  Cutting and pasting is effective for transferring certificates as they are represented as short text files.&lt;br /&gt;
&lt;br /&gt;
Install /etc/apache2/ssl.crt/clientCA.crt from /mit/apache-ssl/certificates/mitCAclient.pem (requires tokens).&lt;br /&gt;
&lt;br /&gt;
Install the rt.conf file from the krbdev-services repository as /etc/apache2/sites-available/rt.conf .&lt;br /&gt;
&lt;br /&gt;
Edit /etc/apache2/mods-available/proxy.conf and set:&lt;br /&gt;
&lt;br /&gt;
  ProxyVia On&lt;br /&gt;
&lt;br /&gt;
  ProxyPass /buildbot/ws ws://krbdev-buildbot.mit.edu:8010/ws&lt;br /&gt;
  ProxyPassReverse /buildbos/ws ws://krbdev-buildbot.mit.edu:8010/ws&lt;br /&gt;
  ProxyPass /buildbot/ http://krbdev-buildbot.mit.edu:8010/&lt;br /&gt;
  ProxyPassReverse /buildbot/ http://krbdev-buildbot.mit.edu:8010/&lt;br /&gt;
  &amp;lt;Proxy http://krbdev-buildbot.mit.edu:8010/*&amp;gt;&lt;br /&gt;
          Allow from all&lt;br /&gt;
  &amp;lt;/Proxy&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Edit /etc/apache2/ports.conf and add &amp;quot;Listen 444&amp;quot; in the ssl_module section after &amp;quot;Listen 443&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Clean out /var/www and install index.html and robots.txt from the krbdev-www directory of the krbdev-services repository.&lt;br /&gt;
&lt;br /&gt;
Run:&lt;br /&gt;
&lt;br /&gt;
  a2enmod ssl&lt;br /&gt;
  a2enmod userdir&lt;br /&gt;
  a2enmod rewrite&lt;br /&gt;
  a2enmod proxy_http&lt;br /&gt;
  a2enmod proxy_wstunnel&lt;br /&gt;
  a2dissite 000-default&lt;br /&gt;
  a2ensite rt&lt;br /&gt;
  service apache2 restart&lt;br /&gt;
&lt;br /&gt;
==Testing==&lt;br /&gt;
&lt;br /&gt;
Get a certificate for the new VM's real hostname and temporarily point /etc/apache2/ssl.crt/server.crt at it.&lt;br /&gt;
&lt;br /&gt;
In /etc/request-tracker4/RT_SiteConfig.pm, temporarily set @ReferrerWhitelist to use the real hostname instead of krbdev.mit.edu.&lt;br /&gt;
&lt;br /&gt;
Temporarily set emergency moderation on the krb5-bugs mailing list (at https://mailman.mit.edu:444/mailman/admin/krb5-bugs/general ) to ensure that mail sent to that list as the result of testing is caught in the moderation queue.&lt;br /&gt;
&lt;br /&gt;
Verify that RT displays at https://realhostname/rt and tickets can be accessed.  Verify that https://realhostname:444/ works and that a new ticket can be created.  Respond to the ticket via email and verify that the response is stored in the ticket.&lt;br /&gt;
&lt;br /&gt;
As root, run /var/rt2/bin/krb5-daily.sh and verify that a dump file appears in /var/psqlbackups.&lt;br /&gt;
&lt;br /&gt;
As rtcvs (&amp;quot;su -s /bin/bash - rtcvs&amp;quot;), run /var/rt2/bin/rt-reserve-ticket and verify that a ticket number is printed.&lt;br /&gt;
&lt;br /&gt;
To test rt-cvsgate, create a test message in /tmp/testmsg like so:&lt;br /&gt;
&lt;br /&gt;
  ticket: new&lt;br /&gt;
  id: NNNN (use the ticket number printed by rt-reserve-ticket above)&lt;br /&gt;
  subject: rt-cvsgate test&lt;br /&gt;
  tags: pullup&lt;br /&gt;
&lt;br /&gt;
  test commit message&lt;br /&gt;
&lt;br /&gt;
As rtcvs, run &amp;quot;/var/rt2/bin/rt-cvsgate ''username'' &amp;lt; /tmp/testmsg&amp;quot;, where ''username'' is an authorized user.&lt;br /&gt;
&lt;br /&gt;
Undo the temporary changes and restore the database from a dump file.&lt;br /&gt;
&lt;br /&gt;
==BIND configuration==&lt;br /&gt;
&lt;br /&gt;
The bind9 configuration files can be found in krbdev-services under bind. They should be installed under /etc/bind. &amp;quot;rndc reload&amp;quot; will restart the runing named with the changed configuration. If it is necessary to edit any of the zone files, be sure to update the serial number in the SOA record to the current date followed by &amp;quot;00&amp;quot; (or &amp;quot;01&amp;quot; etc. for successive edits in the same day).&lt;br /&gt;
&lt;br /&gt;
If the IP address if kerberos.org needs to be changed, the glue record at hover.com must be updated. In the current Hover UI, glue records can be found under &amp;quot;advanced&amp;quot;. The transfer lock on the domain must be temporarily disabled (via the Overview screen) to update glue records.&lt;/div&gt;</summary>
		<author><name>Ghudson</name></author>	</entry>

	<entry>
		<id>https://k5wiki.kerberos.org/wiki?title=RT_server_configuration&amp;diff=6028</id>
		<title>RT server configuration</title>
		<link rel="alternate" type="text/html" href="https://k5wiki.kerberos.org/wiki?title=RT_server_configuration&amp;diff=6028"/>
				<updated>2022-04-12T23:09:22Z</updated>
		
		<summary type="html">&lt;p&gt;Ghudson: /* User accounts */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page contains notes on the setup of the MIT krb5 RT server. The current server is krbdev.mit.edu (canonical name kerborg-prod-app-1.mit.edu), which runs Ubuntu 20.04.&lt;br /&gt;
&lt;br /&gt;
==Packages==&lt;br /&gt;
&lt;br /&gt;
In Ubuntu 20.04, the request-tracker4 package contains a suitable version of RT.  This package will ask some questions at installation time:&lt;br /&gt;
&lt;br /&gt;
* RT site name: krbdev.mit.edu&lt;br /&gt;
* handle RT_SiteConfig.pm permissions: yes&lt;br /&gt;
* use dbconfig-common: no&lt;br /&gt;
&lt;br /&gt;
The data in RT is stored in a PostgreSQL database.  The postgresql Ubuntu package will install the recommended version of PostgreSQL for the current Ubuntu version.&lt;br /&gt;
&lt;br /&gt;
The mail interface to RT is handled by Postfix, so the postfix package is required.  The libsendmail-pmilter-perl package is required for the custom milter script.&lt;br /&gt;
&lt;br /&gt;
The web front end to RT is an Apache2 web server, so the apache2 package is required.  RT uses a FastCGI server, so the libapache2-mod-fcgid package is required.&lt;br /&gt;
&lt;br /&gt;
The server host acts as an authoritative name server for the kerberos.org zone, so the bind9 package must be installed.&lt;br /&gt;
&lt;br /&gt;
In sum, the following packages must be installed on the RT server:&lt;br /&gt;
&lt;br /&gt;
  apache2&lt;br /&gt;
  bind9&lt;br /&gt;
  libapache2-mod-fcgid&lt;br /&gt;
  libsendmail-pmilter-perl&lt;br /&gt;
  perl&lt;br /&gt;
  perl-base&lt;br /&gt;
  postfix&lt;br /&gt;
  postgresql&lt;br /&gt;
  request-tracker4&lt;br /&gt;
&lt;br /&gt;
==User accounts==&lt;br /&gt;
&lt;br /&gt;
The postgresql package will create a postgres user account.&lt;br /&gt;
&lt;br /&gt;
The following user accounts and group entries must be created manually:&lt;br /&gt;
&lt;br /&gt;
* group rt&lt;br /&gt;
* user rtcvs: primary group rt, homedir /var/rt2, shell /bin/sh&lt;br /&gt;
* user rt: primary group rt, homedir /var/rt2, shell /bin/false&lt;br /&gt;
&lt;br /&gt;
These accounts could be created with:&lt;br /&gt;
&lt;br /&gt;
  groupadd -r rt&lt;br /&gt;
  useradd -r -g rt -d /var/rt2 rtcvs&lt;br /&gt;
  useradd -r -m -g rt -d /var/rt2 -s /bin/false rt&lt;br /&gt;
&lt;br /&gt;
Some of the above accounts may be created by ops during provisioning.  /var/rt2 and /var/rt2/.ssh must be owned by rtcvs or sshd will reject logins as rtcvs from drugstore.&lt;br /&gt;
&lt;br /&gt;
For the authoritative repository, create a group named &amp;quot;krbwrite&amp;quot; and an account for each committer, with a root-owned home directory and git-shell configuration:&lt;br /&gt;
&lt;br /&gt;
    groupadd krbwrite&lt;br /&gt;
    useradd -u 3622 -s /usr/bin/git-shell -G krbwrite ghudson&lt;br /&gt;
    mkdir /home/ghudson&lt;br /&gt;
    mkdir /home/ghudson/git-shell-commands&lt;br /&gt;
    ln -s /git/krb5.git/hooks/krb5-rt-id /home/ghudson/git-shell-commands&lt;br /&gt;
&lt;br /&gt;
Create /var/rt2/bin and copy in the following scripts from the krbdev-services repository:&lt;br /&gt;
&lt;br /&gt;
  rt-scripts/rt-reserve-ticket&lt;br /&gt;
  rt-scripts/rtmilter.pl&lt;br /&gt;
  rt-scripts/krb5-daily.sh&lt;br /&gt;
  rt-cvs/rt-cvsgate&lt;br /&gt;
&lt;br /&gt;
The scripts and directory should be mode 755 and owned by user rt and group rt.&lt;br /&gt;
&lt;br /&gt;
/var/rt2 should contain an empty .k5login file, managed by ops.  It should contain a .ssh/authorized_keys file, managed by ops, containing the krbsnap key from hooks/krbsnap_rsa_key.pub in the authoritative repository.&lt;br /&gt;
&lt;br /&gt;
Create /var/psqlbackups (owned by root).&lt;br /&gt;
&lt;br /&gt;
The rt user account is not actually needed for the current RT installation, and the homedir name /var/rt2 is outdated.  The following references need to be taken into account when changing the user and group configuration:&lt;br /&gt;
&lt;br /&gt;
* Both the rt and rtcvs accounts have the homedir /var/rt2.&lt;br /&gt;
* krb5-daily.sh references the krbsnap.keytab file and dumps directory in /var/rt2.&lt;br /&gt;
* A root cron job runs krb5-daily.sh from /var/rt2.&lt;br /&gt;
* A root cron job runs rtmilter on boot from /var/rt2.&lt;br /&gt;
* The empty /var/rt2/.k5login file is managed by ops.&lt;br /&gt;
* The /var/rt2/.ssh/authorized_keys file is managed by ops.&lt;br /&gt;
* The authoritative krb5 git repository rt-ssh-cmd config value references the rtcvs user and /var/rt2/bin/rt-cvsgate.&lt;br /&gt;
* The authoritative krb5 git repository hooks/krb5-rt-id script references the rtcvs user and /var/rt2/bin/rt-reserve-ticket.  This script comes from the krbdev-services repository's githooks/krb5-rt-id.&lt;br /&gt;
* Some of the same references are present in the krbdev-services repository, but they aren't used.&lt;br /&gt;
&lt;br /&gt;
==RT setup==&lt;br /&gt;
&lt;br /&gt;
Install the RT_SiteConfig.pm file from the krbdev-services repository in /etc/request-tracker4.&lt;br /&gt;
&lt;br /&gt;
In root's crontab file (&amp;quot;crontab -e&amp;quot; as root), add the following to perform daily maintenance:&lt;br /&gt;
&lt;br /&gt;
  MAILTO=krbcore-hw@mit.edu&lt;br /&gt;
  0 3 * * * /usr/sbin/rt-clean-sessions&lt;br /&gt;
  0 4 * * * /var/rt2/bin/krb5-daily.sh&lt;br /&gt;
&lt;br /&gt;
==PostgreSQL configuration==&lt;br /&gt;
&lt;br /&gt;
Many PostgreSQL files live in directories specific to the PostgreSQL major and minor version, such as /etc/postgresql/8.3 for PostgreSQL 8.3.&lt;br /&gt;
&lt;br /&gt;
The Ubuntu postgresql package will create a &amp;quot;main&amp;quot; cluster with a configuration directory in /etc/postgresql/&amp;lt;version&amp;gt;/main.&lt;br /&gt;
&lt;br /&gt;
In /etc/postgresql/&amp;lt;version&amp;gt;/main/pg_ident.conf, add:&lt;br /&gt;
&lt;br /&gt;
  local		root		root&lt;br /&gt;
  local		root		postgres&lt;br /&gt;
  local		root		rt_user&lt;br /&gt;
  local		rt		rt_user&lt;br /&gt;
  local		rtcvs		rt_user&lt;br /&gt;
  local		postfix		rt_user&lt;br /&gt;
  local		nobody		rt_user&lt;br /&gt;
  local         www-data        rt_user&lt;br /&gt;
&lt;br /&gt;
(The entry for &amp;quot;rt&amp;quot; should no longer be needed, but is currently still present.)&lt;br /&gt;
&lt;br /&gt;
In /etc/postgresql/&amp;lt;version&amp;gt;/main/pg_hba.conf, find the line that reads &amp;quot;local all all peer&amp;quot; and add &amp;quot;map=local&amp;quot; to the end, so it reads &amp;quot;local all all peer map=local&amp;quot;.  Comment out the line that reads &amp;quot;local all postgres peer&amp;quot;, despite the warning not to disable it.  Run &amp;quot;service postgresql restart&amp;quot; to reread the affected files.  Run &amp;quot;psql -Upostgres --list&amp;quot; to verify that the identity map works.&lt;br /&gt;
&lt;br /&gt;
Run &amp;quot;createuser -Upostgres rt_user&amp;quot; to create the rt_user role.&lt;br /&gt;
&lt;br /&gt;
Run &amp;quot;/usr/sbin/rt-setup-database --action create&amp;quot; to create the database, then restore it from a backup with &amp;quot;zcat /path/to/dump.gz | psql -d rt4 -Upostgres&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==Postfix configuration==&lt;br /&gt;
&lt;br /&gt;
By default ops manages Postfix with Puppet.  This must be disabled by ops, and the Debian defaults restored by copying /usr/share/postfix/main.cf.debian to /etc/postfix/main.cf and /usr/share/postfix/master.cf.dist to /etc/postfix/master.cf.&lt;br /&gt;
&lt;br /&gt;
At the end of /etc/postfix/main.cf add:&lt;br /&gt;
&lt;br /&gt;
  myhostname = krbdev.mit.edu&lt;br /&gt;
  mydestination = krbdev.mit.edu, kerborg-prod-app-1.mit.edu, localhost.mit.edu, localhost&lt;br /&gt;
  &lt;br /&gt;
  # Suppress some headers to avoid leaking internal addresses to spammers.&lt;br /&gt;
  prepend_delivered_header =&lt;br /&gt;
  enable_original_recipient = no&lt;br /&gt;
  &lt;br /&gt;
  # RT header milter&lt;br /&gt;
  smtpd_milters = unix:private/milter&lt;br /&gt;
&lt;br /&gt;
Copy /etc/aliases from the old server.  To avoid aiding spammers, its contents are not reproduced here.  In particular, /etc/aliases contains an internal address corresponding to the membership of the krb5-bugs-incoming mailman list; revealing this address could allow spammers to bypass moderation of incoming bug reports.&lt;br /&gt;
&lt;br /&gt;
In root's crontab file (&amp;quot;crontab -e&amp;quot; as root):&lt;br /&gt;
&lt;br /&gt;
  @reboot /var/rt2/bin/rtmilter.pl /var/spool/postfix/private/milter&lt;br /&gt;
&lt;br /&gt;
Run the command by hand (backgrounded) to start the milter process before the next reboot.&lt;br /&gt;
&lt;br /&gt;
Run &amp;quot;newaliases&amp;quot; and &amp;quot;postfix reload&amp;quot; to pick up the changed configuration.&lt;br /&gt;
&lt;br /&gt;
Make sure rt@kerborg-prod-app-1.mit.edu and rt-comment@kerborg-prod-app-1.mit.edu are authorized as non-member senders at https://mailman.mit.edu:444/mailman/admin/krb5-bugs/privacy/sender .&lt;br /&gt;
&lt;br /&gt;
==Apache httpd configuration==&lt;br /&gt;
&lt;br /&gt;
Create /etc/apache2/ssl.crt and /etc/apache2/ssl.key.&lt;br /&gt;
&lt;br /&gt;
Copy /etc/apache2/ssl.key/server.key and /etc/apache2/ssl.crt/server.crt from the old server, or follow the instructions at http://kb.mit.edu/confluence/display/istcontrib/Obtaining+an+SSL+certificate+for+a+web+server to obtain a new one.  server.key and server.crt may be symlinks using whatever scheme seems convenient for renewing certificates every few years.&lt;br /&gt;
&lt;br /&gt;
Install /etc/apache2/ssl.crt/chain.crt from /mit/apache-ssl/certificates/InCommon-chain.crt.txt (requires tokens).  Cutting and pasting is effective for transferring certificates as they are represented as short text files.&lt;br /&gt;
&lt;br /&gt;
Install /etc/apache2/ssl.crt/clientCA.crt from /mit/apache-ssl/certificates/mitCAclient.pem (requires tokens).&lt;br /&gt;
&lt;br /&gt;
Install the rt.conf file from the krbdev-services repository as /etc/apache2/sites-available/rt.conf .&lt;br /&gt;
&lt;br /&gt;
Edit /etc/apache2/mods-available/proxy.conf and set:&lt;br /&gt;
&lt;br /&gt;
  ProxyVia On&lt;br /&gt;
&lt;br /&gt;
  ProxyPass /buildbot/ws ws://krbdev-buildbot.mit.edu:8010/ws&lt;br /&gt;
  ProxyPassReverse /buildbos/ws ws://krbdev-buildbot.mit.edu:8010/ws&lt;br /&gt;
  ProxyPass /buildbot/ http://krbdev-buildbot.mit.edu:8010/&lt;br /&gt;
  ProxyPassReverse /buildbot/ http://krbdev-buildbot.mit.edu:8010/&lt;br /&gt;
  &amp;lt;Proxy http://krbdev-buildbot.mit.edu:8010/*&amp;gt;&lt;br /&gt;
          Allow from all&lt;br /&gt;
  &amp;lt;/Proxy&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Edit /etc/apache2/ports.conf and add &amp;quot;Listen 444&amp;quot; in the ssl_module section after &amp;quot;Listen 443&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Clean out /var/www and install index.html and robots.txt from the krbdev-www directory of the krbdev-services repository.&lt;br /&gt;
&lt;br /&gt;
Run:&lt;br /&gt;
&lt;br /&gt;
  a2enmod ssl&lt;br /&gt;
  a2enmod userdir&lt;br /&gt;
  a2enmod rewrite&lt;br /&gt;
  a2enmod proxy_http&lt;br /&gt;
  a2enmod proxy_wstunnel&lt;br /&gt;
  a2dissite 000-default&lt;br /&gt;
  a2ensite rt&lt;br /&gt;
  service apache2 restart&lt;br /&gt;
&lt;br /&gt;
==Testing==&lt;br /&gt;
&lt;br /&gt;
Get a certificate for the new VM's real hostname and temporarily point /etc/apache2/ssl.crt/server.crt at it.&lt;br /&gt;
&lt;br /&gt;
In /etc/request-tracker4/RT_SiteConfig.pm, temporarily set @ReferrerWhitelist to use the real hostname instead of krbdev.mit.edu.&lt;br /&gt;
&lt;br /&gt;
Temporarily set emergency moderation on the krb5-bugs mailing list (at https://mailman.mit.edu:444/mailman/admin/krb5-bugs/general ) to ensure that mail sent to that list as the result of testing is caught in the moderation queue.&lt;br /&gt;
&lt;br /&gt;
Verify that RT displays at https://realhostname/rt and tickets can be accessed.  Verify that https://realhostname:444/ works and that a new ticket can be created.  Respond to the ticket via email and verify that the response is stored in the ticket.&lt;br /&gt;
&lt;br /&gt;
As root, run /var/rt2/bin/krb5-daily.sh and verify that a dump file appears in /var/psqlbackups.&lt;br /&gt;
&lt;br /&gt;
As rtcvs (&amp;quot;su -s /bin/bash - rtcvs&amp;quot;), run /var/rt2/bin/rt-reserve-ticket and verify that a ticket number is printed.&lt;br /&gt;
&lt;br /&gt;
To test rt-cvsgate, create a test message in /tmp/testmsg like so:&lt;br /&gt;
&lt;br /&gt;
  ticket: new&lt;br /&gt;
  id: NNNN (use the ticket number printed by rt-reserve-ticket above)&lt;br /&gt;
  subject: rt-cvsgate test&lt;br /&gt;
  tags: pullup&lt;br /&gt;
&lt;br /&gt;
  test commit message&lt;br /&gt;
&lt;br /&gt;
As rtcvs, run &amp;quot;/var/rt2/bin/rt-cvsgate ''username'' &amp;lt; /tmp/testmsg&amp;quot;, where ''username'' is an authorized user.&lt;br /&gt;
&lt;br /&gt;
Undo the temporary changes and restore the database from a dump file.&lt;br /&gt;
&lt;br /&gt;
==BIND configuration==&lt;br /&gt;
&lt;br /&gt;
The bind9 configuration files can be found in krbdev-services under bind. They should be installed under /etc/bind. &amp;quot;rndc reload&amp;quot; will restart the runing named with the changed configuration. If it is necessary to edit any of the zone files, be sure to update the serial number in the SOA record to the current date followed by &amp;quot;00&amp;quot; (or &amp;quot;01&amp;quot; etc. for successive edits in the same day).&lt;br /&gt;
&lt;br /&gt;
If the IP address if kerberos.org needs to be changed, the glue record at hover.com must be updated. In the current Hover UI, glue records can be found under &amp;quot;advanced&amp;quot;. The transfer lock on the domain must be temporarily disabled (via the Overview screen) to update glue records.&lt;/div&gt;</summary>
		<author><name>Ghudson</name></author>	</entry>

	<entry>
		<id>https://k5wiki.kerberos.org/wiki?title=Getting_source_code&amp;diff=6027</id>
		<title>Getting source code</title>
		<link rel="alternate" type="text/html" href="https://k5wiki.kerberos.org/wiki?title=Getting_source_code&amp;diff=6027"/>
				<updated>2021-12-14T20:21:10Z</updated>
		
		<summary type="html">&lt;p&gt;Ghudson: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The MIT Kerberos source code is in a Git repository.&lt;br /&gt;
&lt;br /&gt;
== Official releases ==&lt;br /&gt;
&lt;br /&gt;
Typically, end users and system administrators who want the latest stable MIT krb5 software should use the official releases:&lt;br /&gt;
&lt;br /&gt;
* [http://web.mit.edu/kerberos/dist/ MIT Keberos download page]&lt;br /&gt;
&lt;br /&gt;
== Git repository access ==&lt;br /&gt;
&lt;br /&gt;
The current development source code is now in a Git repository. The latest development code is on the &amp;quot;master&amp;quot; branch, as is usual for Git. (It used to be &amp;quot;trunk&amp;quot; when the main repository was in Subversion.) Developers wishing to contribute changes to the krb5 software should track this repository. Advanced end users and system administrators may also wish to obtain the latest development sources from this repository.&lt;br /&gt;
&lt;br /&gt;
The krb5 repository migrated to Git during the weekend of 2012-05-11. Use the following URLs for read-only access.&lt;br /&gt;
&lt;br /&gt;
* git://github.com/krb5/krb5.git for the public read-only Git access&lt;br /&gt;
* https://github.com/krb5/krb5 for browsing&lt;br /&gt;
&lt;br /&gt;
If you are interested in contributing changes to our repository, please consult our [[Coding style/Version control practices | version control practices]] page. You should of course test changes before submitting them for inclusion; see [[Building]] for the additional steps needed to build from a git checkout and [[Test suite]] for more information about the regression tests. Additional information about the [[Git migration]] is available, including help for situations where you have an existing GitHub fork of the krb5-anonsvn Git repository.&lt;br /&gt;
&lt;br /&gt;
There is a wiki page with details about the [[Git conversion]] process available for people who are interested in the technical details.&lt;br /&gt;
&lt;br /&gt;
== Repository browsing ==&lt;br /&gt;
&lt;br /&gt;
* https://github.com/krb5/krb5 for browsing on GitHub&lt;/div&gt;</summary>
		<author><name>Ghudson</name></author>	</entry>

	<entry>
		<id>https://k5wiki.kerberos.org/wiki?title=TGS_Requests&amp;diff=6026</id>
		<title>TGS Requests</title>
		<link rel="alternate" type="text/html" href="https://k5wiki.kerberos.org/wiki?title=TGS_Requests&amp;diff=6026"/>
				<updated>2021-12-09T07:19:31Z</updated>
		
		<summary type="html">&lt;p&gt;Ghudson: /* References */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Kerberos Ticket Granting Service (TGS) requests are one of the most complicated areas of processing in MIT krb5, in both the client and the KDC.  Here are some notes on the different kind of TGS requests and what considerations must be made when processing them.&lt;br /&gt;
&lt;br /&gt;
==Protocol structure==&lt;br /&gt;
&lt;br /&gt;
Like an AS request, a TGS request contains a KDC-REQ-BODY sequence and a sequence of PA-DATA.  One of the pa-data elements will have type PA-TGS-REQ; its value will contain an AP-REQ, the same protocol structure a client would use to authenticate to an application server.  The ticket in the AP-REQ is called the &amp;quot;header ticket&amp;quot; within the MIT KDC source code, because {{rfcref|4120}} uses the term &amp;quot;authentication header&amp;quot; to refer to the AP-REQ.&lt;br /&gt;
&lt;br /&gt;
The authenticator in the AP-REQ contains a checksum over the encoding of the body.  This checksum need not be keyed, as it is contained within an encrypted payload, but with modern encryption types it is usually a keyed checksum anyway.  There is no intrinsic cryptographic binding between other padata elements and the PA-TGS-REQ or the body.&lt;br /&gt;
&lt;br /&gt;
The authenticator in the AP-REQ may contain a subkey, in which case the TGS response should be encrypted in the subkey.  Otherwise it should be encrypted in the session key of the header ticket.  There are four historical interoperability bugs affecting the use of subkeys in TGS requests, as described here:&lt;br /&gt;
&lt;br /&gt;
  https://mailarchive.ietf.org/arch/msg/krb-wg/DD8CFMuWiHJhkkoHGbjx0Z1dpKo&lt;br /&gt;
  https://mailarchive.ietf.org/arch/msg/krb-wg/4qhYxn7iovCnfsHL8wmim7-8Tq0&lt;br /&gt;
  https://mailarchive.ietf.org/arch/msg/krb-wg/hl6PvUz94IQMFadSybnjGYeBCCE&lt;br /&gt;
&lt;br /&gt;
TGS requests may use FAST implicit armor ({{rfcref|6113}} section 5.4).  In this case one of the pa-data elements will have type PA-FX-FAST and its value will contain a second copy of the TGS request encrypted in a key derived from the subkey (which must be present) and the ticket session key.&lt;br /&gt;
&lt;br /&gt;
==Normal TGS requests==&lt;br /&gt;
&lt;br /&gt;
For the purposes of this article, a TGS request is considered &amp;quot;normal&amp;quot; if it:&lt;br /&gt;
&lt;br /&gt;
* does not have any of the forwarded, proxy, renew, validate, enc-tkt-in-skey, or cname-in-addl-tkt options&lt;br /&gt;
* does not contain PA-FOR-USER or PA_S4U_X509_USER pa-data.&lt;br /&gt;
&lt;br /&gt;
The header ticket for a normal TGS request server have an sname field of krbtgt/THIS.REALM, where THIS.REALM must match the realm field of the TGS request.  If the header ticket is a cross-realm TGT (the ticket's srealm field is some OTHER.REALM different from THIS.REALM), the ticket's crealm must also be different from THIS.REALM; this is called the &amp;quot;lineage check&amp;quot;, and ensures that foreign realms cannot issue tickets for local users.  The KDC also (unless requested not to) checks the transited list in the ticket to ensure that OTHER.REALM has the authority to issue tickets for the realm of the header ticket client, and adds OTHER.REALM to the transited list of the issued ticket if it does not match the realm of the header ticket client.&lt;br /&gt;
&lt;br /&gt;
If the requested server is a TGS principal for a different realm, the KDC may issue a ticket to an alternative TGS principal for an intermediate realm instead.  If the requested server is not a TGS server but the request has the &amp;quot;canonicalize&amp;quot; KDC option set ({{rfcref|6803}} section 3), the KDC may issue a ticket to an outgoing TGS principal; this is called a &amp;quot;referral&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
For local clients, some KDC implementations look up the client DB entry and apply the entry's policy in case it has changed (e.g. the account has been revoked).  The MIT krb5 KDC does not currently do this.&lt;br /&gt;
&lt;br /&gt;
It is possible for an otherwise normal TGS request to be part of a cross-realm Resource-Based Constrained Delegation (RBCD) operation transiting through this realm.  In this case, the header ticket will be a cross-realm TGT, the request server will be a cross-realm TGS, the header ticket PAC will contain an S4U_DELEGATION_INFO buffer giving the ticket client as the last transited service, and the PAC_CLIENT_INFO buffer will contain a realm part in the name.  These requests can be processed the same way as a normal TGS request, but when issuing a PAC for the resulting ticket the KDC must copy the PAC_CLIENT_INFO and S4U_DELEGATION_INFO buffers from the header ticket.&lt;br /&gt;
&lt;br /&gt;
==Ticket modification requests==&lt;br /&gt;
&lt;br /&gt;
A ticket modification request has the forwarded, proxy, renew, or validate option.  The header ticket is not required to be a TGT, and must not be a TGT if the proxy option is requested.  The request sname must match the ticket sname, and the KDC must not be issuing a referral.  The header ticket must have a flag corresponding to the requested option (forwardable for forwarded, etc.)  The issued ticket will be similar in most respects to the header ticket, except for the addresses, validity times, and invalid flag as indicated by the request option.&lt;br /&gt;
&lt;br /&gt;
==User-to-user requests==&lt;br /&gt;
&lt;br /&gt;
If the enc-tkt-in-skey option is requested, the request must contain a second ticket in the additional-tickets field.  The second ticket must be a local-realm TGT for the server realm (krbtgt/THIS.REALM@THIS.REALM), and the second ticket cname and crealm must match the request sname and realm.  The request is processed similarly to a normal request, but the resulting ticket will be encrypted in the session key of the second ticket, and will have a session key of the same type as the second ticket's.  User-to-user requests cannot generate referrals.&lt;br /&gt;
&lt;br /&gt;
==S4U2Self (protocol transition) requests==&lt;br /&gt;
&lt;br /&gt;
If the request pa-data contains an element of type PA-FOR-USER or PA_S4U_X509_USER or both, it is a request to issue a ticket from a named user (known as the &amp;quot;subject&amp;quot;) to the requesting service.  The subject may be identified by principal or by X.509 certificate.  S4U2Self requests do not require special privileges, although in some cases the forwardable flag will be cleared on the resulting ticket.  S4U2Self requests must not contain any options for other kinds of special TGS requests (ticket modification, user-to-user, and S4U2Proxy).&lt;br /&gt;
&lt;br /&gt;
For a local-realm S4U2Self requests, the request server must match the header ticket client, although they may use different aliases for the same principal.  A PAC must be present in the header ticket, although it is not used as a basis for the PAC in the issued ticket.  The subject is looked up in the database, checked for policy constraints, and a PAC is issued for it as it would be for an AS request.  Authentication indicators are not copied from the header ticket, as there was no actual authentication of the subject.&lt;br /&gt;
&lt;br /&gt;
For cross-realm S4U2Self scenarios, there are four different kinds of requests:&lt;br /&gt;
&lt;br /&gt;
1. Zero or more AS requests to determine the subject realm, if it is not already known.  These may be ordinary AS requests, but they may also contain PA_S4U_X509_USER if the user is identified by a certificate.  The requesting service begins at the service realm and follows the chain of KDC_ERR_WRONG_REALM errors until a KDC_ERR_PREAUTH_REQUIRED error is received or a ticket is issued, indicating that the subject realm is known.  The requesting server then obtains a cross-realm TGT to the subject realm using ordinary TGS requests.&lt;br /&gt;
&lt;br /&gt;
2. A cross-realm S4U2Self request to the subject realm.  Since the requesting service does not live in this realm, the request server will contain the representation of a requesting service as an enterprise principal.  As for a local S4U2Self request, the subject realm KDC looks up the subject in the database, checks it for policy constraints, and constructs a PAC for the subject.  Unlike a local request, the PAC_CLIENT_INFO name in the PAC will contain an &amp;quot;@REALM&amp;quot; suffix identifying the subject realm, and the KDC issues a referral TGT back towards the service realm.  The reply includes PA_S4U_X509_USER naming the subject principal, in case a certificate was used to identify it.&lt;br /&gt;
&lt;br /&gt;
3. Zero or more cross-realm S4U2Self requests to intermediate realms along the path back to the service realm, each resulting in a referral TGT.  The S4U2Self padata in these requests must contain the subject principal name; the subject can no longer be identified by certificate at this step.  As in step 2, the PAC in the issued referral TGTs must be for the subject and must contain an &amp;quot;@REALM&amp;quot; suffix in the PAC_CLIENT_INFO name.&lt;br /&gt;
&lt;br /&gt;
4. A cross-realm S4U2Self request to the service realm.  This type of request would ordinarily fail the lineage check (as the client is in the local realm and the TGT was issued by another realm), so S4U2Self requests are excepted from this check.  The service realm KDC issues a ticket from the subject to the requesting service, using the PAC in the the referral ticket as a basis.  However, the PAC_CLIENT_INFO name for the PAC does not contain the &amp;quot;@REALM&amp;quot; suffix.&lt;br /&gt;
&lt;br /&gt;
S4U2Self requests override the no_authdata_required flag on the requesting service principal.  Although the service may not require authorization data for tickets received from clients, its use of S4U2Self strongly suggests the need for a PAC--either the service plans to make an S4U2Proxy request, or it has a special need to inspect the PAC for a subject.&lt;br /&gt;
&lt;br /&gt;
If the requesting service has any outgoing constrained delegation privileges, but does not have the ok_to_auth_as_delegate principal flag, then the forwardable ticket flag will be suppressed on tickets issued to it via S4U2Self.  The intent is to prevent the use of S4U2Self-issued tickets as S4U2Proxy evidence tickets without this extra privilege when outgoing authorizations are used (but not when the delegation is allowed by an incoming authorization on the delegation target).&lt;br /&gt;
&lt;br /&gt;
==S4U2Proxy (constrained delegation) requests==&lt;br /&gt;
&lt;br /&gt;
If the cname-in-addl-tkt option is requested, the request is for a ticket from some client (known here as the &amp;quot;subject&amp;quot;) to another service.  The request must contain a second ticket (known as the &amp;quot;subject ticket&amp;quot; or &amp;quot;evidence ticket&amp;quot;) in the additional-tickets field to identify the subject.  The subject ticket must have the forwardable flag set.  The request must not contain any options or padata for other kinds of special TGS requests (ticket modification, user-to-user, or S4U2Self).  S4U2Proxy operations require special privileges, which may be modeled as outgoing delegation privileges on the requesting service or incoming delegation privileges on the delegation target.  When incoming delegation privileges are used, the operation is known as resource-based constrained delegation (RBCD) and the delegation target may be in a different realm from the requesting service.  Otherwise, the requesting service and delegation target must be in the same realm.&lt;br /&gt;
&lt;br /&gt;
There are three parties to an S4U2Proxy operation:&lt;br /&gt;
&lt;br /&gt;
1. The subject, which will be the cname and crealm of the resulting ticket.  This party may also be known as the &amp;quot;client&amp;quot;, although that term may be confused for the requesting service.  For a local-realm S4U2Proxy or initial RBCD request, this is the client of the subject ticket.  For a cross-realm RBCD request, the subject is identified by the PAC in the subject ticket.&lt;br /&gt;
&lt;br /&gt;
2. The requesting service, as give by the client of the header ticket.  This may also be known as the impersonator.&lt;br /&gt;
&lt;br /&gt;
3. The delegation target, which will be the sname and realm of the resulting ticket.  This party may also be known as the &amp;quot;resource&amp;quot;, the &amp;quot;server&amp;quot; (because it is given by the sname and realm of the KDC request), the &amp;quot;proxy target&amp;quot;, or (particularly in Microsoft documentation) just the &amp;quot;proxy&amp;quot;.  Experience has shown that the term &amp;quot;proxy&amp;quot; is easily confused with the impersonator, so the MIT implementation uses this term sparingly.  The delegation target must not be a TGS name.&lt;br /&gt;
&lt;br /&gt;
A PAC must be present in both the header ticket and subject ticket.  For a cross-realm RBCD request, the PAC must contain an S4U_DELEGATION_INFO buffer with the requesting service as the last transited_service and the delegation target as the proxy_target, and an &amp;quot;@REALM&amp;quot; suffix in the PAC_CLIENT_INFO name.  For a local S4U2Proxy request, the PAC must be for the second ticket client.  The PAC in the header ticket must be for the requesting service.&lt;br /&gt;
&lt;br /&gt;
For a local-realm or initial RBCD request, the KDC adds S4U_DELEGATION_INFO to the PAC in the issued service ticket or referral TGT.  Any transited services specified in the subject PAC's delegation info (if it had one) are copied, and the requesting service is added to the end.  The proxy_target field is set to the delegation target.  Final RBCD requests verify and copy delegation info from the subject PAC without modifying it.&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
&lt;br /&gt;
RFC 4120 specifies the base Kerberos 5 protocol.&lt;br /&gt;
&lt;br /&gt;
RFC 6113 specifies FAST.&lt;br /&gt;
&lt;br /&gt;
RFC 6803 specifies referrals.&lt;br /&gt;
&lt;br /&gt;
S4U2Self and S4U2Proxy are fully specified in [https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-sfu/3bff5864-8135-400e-bdd9-33b552051d94 [MS-SFU]].&lt;br /&gt;
&lt;br /&gt;
PACs are specified in [https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-pac/166d8064-c863-41e1-9c23-edaaa5f36962 [MS-PAC]].&lt;/div&gt;</summary>
		<author><name>Ghudson</name></author>	</entry>

	<entry>
		<id>https://k5wiki.kerberos.org/wiki?title=TGS_Requests&amp;diff=6025</id>
		<title>TGS Requests</title>
		<link rel="alternate" type="text/html" href="https://k5wiki.kerberos.org/wiki?title=TGS_Requests&amp;diff=6025"/>
				<updated>2021-12-09T07:15:40Z</updated>
		
		<summary type="html">&lt;p&gt;Ghudson: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Kerberos Ticket Granting Service (TGS) requests are one of the most complicated areas of processing in MIT krb5, in both the client and the KDC.  Here are some notes on the different kind of TGS requests and what considerations must be made when processing them.&lt;br /&gt;
&lt;br /&gt;
==Protocol structure==&lt;br /&gt;
&lt;br /&gt;
Like an AS request, a TGS request contains a KDC-REQ-BODY sequence and a sequence of PA-DATA.  One of the pa-data elements will have type PA-TGS-REQ; its value will contain an AP-REQ, the same protocol structure a client would use to authenticate to an application server.  The ticket in the AP-REQ is called the &amp;quot;header ticket&amp;quot; within the MIT KDC source code, because {{rfcref|4120}} uses the term &amp;quot;authentication header&amp;quot; to refer to the AP-REQ.&lt;br /&gt;
&lt;br /&gt;
The authenticator in the AP-REQ contains a checksum over the encoding of the body.  This checksum need not be keyed, as it is contained within an encrypted payload, but with modern encryption types it is usually a keyed checksum anyway.  There is no intrinsic cryptographic binding between other padata elements and the PA-TGS-REQ or the body.&lt;br /&gt;
&lt;br /&gt;
The authenticator in the AP-REQ may contain a subkey, in which case the TGS response should be encrypted in the subkey.  Otherwise it should be encrypted in the session key of the header ticket.  There are four historical interoperability bugs affecting the use of subkeys in TGS requests, as described here:&lt;br /&gt;
&lt;br /&gt;
  https://mailarchive.ietf.org/arch/msg/krb-wg/DD8CFMuWiHJhkkoHGbjx0Z1dpKo&lt;br /&gt;
  https://mailarchive.ietf.org/arch/msg/krb-wg/4qhYxn7iovCnfsHL8wmim7-8Tq0&lt;br /&gt;
  https://mailarchive.ietf.org/arch/msg/krb-wg/hl6PvUz94IQMFadSybnjGYeBCCE&lt;br /&gt;
&lt;br /&gt;
TGS requests may use FAST implicit armor ({{rfcref|6113}} section 5.4).  In this case one of the pa-data elements will have type PA-FX-FAST and its value will contain a second copy of the TGS request encrypted in a key derived from the subkey (which must be present) and the ticket session key.&lt;br /&gt;
&lt;br /&gt;
==Normal TGS requests==&lt;br /&gt;
&lt;br /&gt;
For the purposes of this article, a TGS request is considered &amp;quot;normal&amp;quot; if it:&lt;br /&gt;
&lt;br /&gt;
* does not have any of the forwarded, proxy, renew, validate, enc-tkt-in-skey, or cname-in-addl-tkt options&lt;br /&gt;
* does not contain PA-FOR-USER or PA_S4U_X509_USER pa-data.&lt;br /&gt;
&lt;br /&gt;
The header ticket for a normal TGS request server have an sname field of krbtgt/THIS.REALM, where THIS.REALM must match the realm field of the TGS request.  If the header ticket is a cross-realm TGT (the ticket's srealm field is some OTHER.REALM different from THIS.REALM), the ticket's crealm must also be different from THIS.REALM; this is called the &amp;quot;lineage check&amp;quot;, and ensures that foreign realms cannot issue tickets for local users.  The KDC also (unless requested not to) checks the transited list in the ticket to ensure that OTHER.REALM has the authority to issue tickets for the realm of the header ticket client, and adds OTHER.REALM to the transited list of the issued ticket if it does not match the realm of the header ticket client.&lt;br /&gt;
&lt;br /&gt;
If the requested server is a TGS principal for a different realm, the KDC may issue a ticket to an alternative TGS principal for an intermediate realm instead.  If the requested server is not a TGS server but the request has the &amp;quot;canonicalize&amp;quot; KDC option set ({{rfcref|6803}} section 3), the KDC may issue a ticket to an outgoing TGS principal; this is called a &amp;quot;referral&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
For local clients, some KDC implementations look up the client DB entry and apply the entry's policy in case it has changed (e.g. the account has been revoked).  The MIT krb5 KDC does not currently do this.&lt;br /&gt;
&lt;br /&gt;
It is possible for an otherwise normal TGS request to be part of a cross-realm Resource-Based Constrained Delegation (RBCD) operation transiting through this realm.  In this case, the header ticket will be a cross-realm TGT, the request server will be a cross-realm TGS, the header ticket PAC will contain an S4U_DELEGATION_INFO buffer giving the ticket client as the last transited service, and the PAC_CLIENT_INFO buffer will contain a realm part in the name.  These requests can be processed the same way as a normal TGS request, but when issuing a PAC for the resulting ticket the KDC must copy the PAC_CLIENT_INFO and S4U_DELEGATION_INFO buffers from the header ticket.&lt;br /&gt;
&lt;br /&gt;
==Ticket modification requests==&lt;br /&gt;
&lt;br /&gt;
A ticket modification request has the forwarded, proxy, renew, or validate option.  The header ticket is not required to be a TGT, and must not be a TGT if the proxy option is requested.  The request sname must match the ticket sname, and the KDC must not be issuing a referral.  The header ticket must have a flag corresponding to the requested option (forwardable for forwarded, etc.)  The issued ticket will be similar in most respects to the header ticket, except for the addresses, validity times, and invalid flag as indicated by the request option.&lt;br /&gt;
&lt;br /&gt;
==User-to-user requests==&lt;br /&gt;
&lt;br /&gt;
If the enc-tkt-in-skey option is requested, the request must contain a second ticket in the additional-tickets field.  The second ticket must be a local-realm TGT for the server realm (krbtgt/THIS.REALM@THIS.REALM), and the second ticket cname and crealm must match the request sname and realm.  The request is processed similarly to a normal request, but the resulting ticket will be encrypted in the session key of the second ticket, and will have a session key of the same type as the second ticket's.  User-to-user requests cannot generate referrals.&lt;br /&gt;
&lt;br /&gt;
==S4U2Self (protocol transition) requests==&lt;br /&gt;
&lt;br /&gt;
If the request pa-data contains an element of type PA-FOR-USER or PA_S4U_X509_USER or both, it is a request to issue a ticket from a named user (known as the &amp;quot;subject&amp;quot;) to the requesting service.  The subject may be identified by principal or by X.509 certificate.  S4U2Self requests do not require special privileges, although in some cases the forwardable flag will be cleared on the resulting ticket.  S4U2Self requests must not contain any options for other kinds of special TGS requests (ticket modification, user-to-user, and S4U2Proxy).&lt;br /&gt;
&lt;br /&gt;
For a local-realm S4U2Self requests, the request server must match the header ticket client, although they may use different aliases for the same principal.  A PAC must be present in the header ticket, although it is not used as a basis for the PAC in the issued ticket.  The subject is looked up in the database, checked for policy constraints, and a PAC is issued for it as it would be for an AS request.  Authentication indicators are not copied from the header ticket, as there was no actual authentication of the subject.&lt;br /&gt;
&lt;br /&gt;
For cross-realm S4U2Self scenarios, there are four different kinds of requests:&lt;br /&gt;
&lt;br /&gt;
1. Zero or more AS requests to determine the subject realm, if it is not already known.  These may be ordinary AS requests, but they may also contain PA_S4U_X509_USER if the user is identified by a certificate.  The requesting service begins at the service realm and follows the chain of KDC_ERR_WRONG_REALM errors until a KDC_ERR_PREAUTH_REQUIRED error is received or a ticket is issued, indicating that the subject realm is known.  The requesting server then obtains a cross-realm TGT to the subject realm using ordinary TGS requests.&lt;br /&gt;
&lt;br /&gt;
2. A cross-realm S4U2Self request to the subject realm.  Since the requesting service does not live in this realm, the request server will contain the representation of a requesting service as an enterprise principal.  As for a local S4U2Self request, the subject realm KDC looks up the subject in the database, checks it for policy constraints, and constructs a PAC for the subject.  Unlike a local request, the PAC_CLIENT_INFO name in the PAC will contain an &amp;quot;@REALM&amp;quot; suffix identifying the subject realm, and the KDC issues a referral TGT back towards the service realm.  The reply includes PA_S4U_X509_USER naming the subject principal, in case a certificate was used to identify it.&lt;br /&gt;
&lt;br /&gt;
3. Zero or more cross-realm S4U2Self requests to intermediate realms along the path back to the service realm, each resulting in a referral TGT.  The S4U2Self padata in these requests must contain the subject principal name; the subject can no longer be identified by certificate at this step.  As in step 2, the PAC in the issued referral TGTs must be for the subject and must contain an &amp;quot;@REALM&amp;quot; suffix in the PAC_CLIENT_INFO name.&lt;br /&gt;
&lt;br /&gt;
4. A cross-realm S4U2Self request to the service realm.  This type of request would ordinarily fail the lineage check (as the client is in the local realm and the TGT was issued by another realm), so S4U2Self requests are excepted from this check.  The service realm KDC issues a ticket from the subject to the requesting service, using the PAC in the the referral ticket as a basis.  However, the PAC_CLIENT_INFO name for the PAC does not contain the &amp;quot;@REALM&amp;quot; suffix.&lt;br /&gt;
&lt;br /&gt;
S4U2Self requests override the no_authdata_required flag on the requesting service principal.  Although the service may not require authorization data for tickets received from clients, its use of S4U2Self strongly suggests the need for a PAC--either the service plans to make an S4U2Proxy request, or it has a special need to inspect the PAC for a subject.&lt;br /&gt;
&lt;br /&gt;
If the requesting service has any outgoing constrained delegation privileges, but does not have the ok_to_auth_as_delegate principal flag, then the forwardable ticket flag will be suppressed on tickets issued to it via S4U2Self.  The intent is to prevent the use of S4U2Self-issued tickets as S4U2Proxy evidence tickets without this extra privilege when outgoing authorizations are used (but not when the delegation is allowed by an incoming authorization on the delegation target).&lt;br /&gt;
&lt;br /&gt;
==S4U2Proxy (constrained delegation) requests==&lt;br /&gt;
&lt;br /&gt;
If the cname-in-addl-tkt option is requested, the request is for a ticket from some client (known here as the &amp;quot;subject&amp;quot;) to another service.  The request must contain a second ticket (known as the &amp;quot;subject ticket&amp;quot; or &amp;quot;evidence ticket&amp;quot;) in the additional-tickets field to identify the subject.  The subject ticket must have the forwardable flag set.  The request must not contain any options or padata for other kinds of special TGS requests (ticket modification, user-to-user, or S4U2Self).  S4U2Proxy operations require special privileges, which may be modeled as outgoing delegation privileges on the requesting service or incoming delegation privileges on the delegation target.  When incoming delegation privileges are used, the operation is known as resource-based constrained delegation (RBCD) and the delegation target may be in a different realm from the requesting service.  Otherwise, the requesting service and delegation target must be in the same realm.&lt;br /&gt;
&lt;br /&gt;
There are three parties to an S4U2Proxy operation:&lt;br /&gt;
&lt;br /&gt;
1. The subject, which will be the cname and crealm of the resulting ticket.  This party may also be known as the &amp;quot;client&amp;quot;, although that term may be confused for the requesting service.  For a local-realm S4U2Proxy or initial RBCD request, this is the client of the subject ticket.  For a cross-realm RBCD request, the subject is identified by the PAC in the subject ticket.&lt;br /&gt;
&lt;br /&gt;
2. The requesting service, as give by the client of the header ticket.  This may also be known as the impersonator.&lt;br /&gt;
&lt;br /&gt;
3. The delegation target, which will be the sname and realm of the resulting ticket.  This party may also be known as the &amp;quot;resource&amp;quot;, the &amp;quot;server&amp;quot; (because it is given by the sname and realm of the KDC request), the &amp;quot;proxy target&amp;quot;, or (particularly in Microsoft documentation) just the &amp;quot;proxy&amp;quot;.  Experience has shown that the term &amp;quot;proxy&amp;quot; is easily confused with the impersonator, so the MIT implementation uses this term sparingly.  The delegation target must not be a TGS name.&lt;br /&gt;
&lt;br /&gt;
A PAC must be present in both the header ticket and subject ticket.  For a cross-realm RBCD request, the PAC must contain an S4U_DELEGATION_INFO buffer with the requesting service as the last transited_service and the delegation target as the proxy_target, and an &amp;quot;@REALM&amp;quot; suffix in the PAC_CLIENT_INFO name.  For a local S4U2Proxy request, the PAC must be for the second ticket client.  The PAC in the header ticket must be for the requesting service.&lt;br /&gt;
&lt;br /&gt;
For a local-realm or initial RBCD request, the KDC adds S4U_DELEGATION_INFO to the PAC in the issued service ticket or referral TGT.  Any transited services specified in the subject PAC's delegation info (if it had one) are copied, and the requesting service is added to the end.  The proxy_target field is set to the delegation target.  Final RBCD requests verify and copy delegation info from the subject PAC without modifying it.&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
&lt;br /&gt;
S4U2Self and S4U2Proxy are fully specified in [https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-sfu/3bff5864-8135-400e-bdd9-33b552051d94 [MS-SFU]].&lt;br /&gt;
&lt;br /&gt;
PACs are specified in [https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-pac/166d8064-c863-41e1-9c23-edaaa5f36962 [MS-PAC]].&lt;/div&gt;</summary>
		<author><name>Ghudson</name></author>	</entry>

	<entry>
		<id>https://k5wiki.kerberos.org/wiki?title=TGS_Requests&amp;diff=6024</id>
		<title>TGS Requests</title>
		<link rel="alternate" type="text/html" href="https://k5wiki.kerberos.org/wiki?title=TGS_Requests&amp;diff=6024"/>
				<updated>2021-12-09T06:36:03Z</updated>
		
		<summary type="html">&lt;p&gt;Ghudson: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Kerberos Ticket Granting Service (TGS) requests are one of the most complicated areas of processing in MIT krb5, in both the client and the KDC.  Here are some notes on the different kind of TGS requests and what considerations must be made when processing them.&lt;br /&gt;
&lt;br /&gt;
==Protocol structure==&lt;br /&gt;
&lt;br /&gt;
Like an AS request, a TGS request contains a KDC-REQ-BODY sequence and a sequence of PA-DATA.  One of the pa-data elements will have type PA-TGS-REQ; its value will contain an AP-REQ, the same protocol structure a client would use to authenticate to an application server.  The ticket in the AP-REQ is called the &amp;quot;header ticket&amp;quot; within the MIT KDC source code, because {{rfcref|4120}} uses the term &amp;quot;authentication header&amp;quot; to refer to the AP-REQ.&lt;br /&gt;
&lt;br /&gt;
The authenticator in the AP-REQ contains a checksum over the encoding of the body.  This checksum need not be keyed, as it is contained within an encrypted payload, but with modern encryption types it is usually a keyed checksum anyway.  There is no intrinsic cryptographic binding between other padata elements and the PA-TGS-REQ or the body.&lt;br /&gt;
&lt;br /&gt;
The authenticator in the AP-REQ may contain a subkey, in which case the TGS response should be encrypted in the subkey.  Otherwise it should be encrypted in the session key of the header ticket.  There are four historical interoperability bugs affecting the use of subkeys in TGS requests, as described here:&lt;br /&gt;
&lt;br /&gt;
  https://mailarchive.ietf.org/arch/msg/krb-wg/DD8CFMuWiHJhkkoHGbjx0Z1dpKo&lt;br /&gt;
  https://mailarchive.ietf.org/arch/msg/krb-wg/4qhYxn7iovCnfsHL8wmim7-8Tq0&lt;br /&gt;
  https://mailarchive.ietf.org/arch/msg/krb-wg/hl6PvUz94IQMFadSybnjGYeBCCE&lt;br /&gt;
&lt;br /&gt;
TGS requests may use FAST implicit armor ({{rfcref|6113}} section 5.4).  In this case one of the pa-data elements will have type PA-FX-FAST and its value will contain a second copy of the TGS request encrypted in a key derived from the subkey (which must be present) and the ticket session key.&lt;br /&gt;
&lt;br /&gt;
==Types of TGS requests==&lt;br /&gt;
&lt;br /&gt;
* Normal&lt;br /&gt;
&lt;br /&gt;
* Ticket modification&lt;br /&gt;
&lt;br /&gt;
* User-to-user&lt;br /&gt;
&lt;br /&gt;
* S4U2Self (aka &amp;quot;protocol transition&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
* S4U2Proxy (aka &amp;quot;constrained delegation&amp;quot;): if the CNAME-IN-ADDL-TICKET option is requested, the request body must contain an additional ticket (called the &amp;quot;evidence ticket&amp;quot;) from a user to the requesting service--or, for a cross-realm request, a cross-TGT containing a PAC or equivalent authorization data for a user.  If delegation is allowed to the requested server, the KDC issues a ticket from the evidence ticket client (or the client named in the PAC) to the requested server.  S4U2Proxy is specified in the same document as S4U2Self.&lt;br /&gt;
&lt;br /&gt;
==Normal TGS requests==&lt;br /&gt;
&lt;br /&gt;
For the purposes of this article, a TGS request is considered &amp;quot;normal&amp;quot; if it:&lt;br /&gt;
&lt;br /&gt;
* does not have any of the forwarded, proxy, renew, validate, enc-tkt-in-skey, or cname-in-addl-tkt options&lt;br /&gt;
* does not contain PA-FOR-USER or PA_S4U_X509_USER pa-data.&lt;br /&gt;
&lt;br /&gt;
The header ticket for a normal TGS request server have an sname field of krbtgt/THIS.REALM, where THIS.REALM must match the realm field of the TGS request.  If the header ticket is a cross-realm TGT (the ticket's srealm field is some OTHER.REALM different from THIS.REALM), the ticket's crealm must also be different from THIS.REALM; this is called the &amp;quot;lineage check&amp;quot;, and ensures that foreign realms cannot issue tickets for local users.  The KDC also (unless requested not to) checks the transited list in the ticket to ensure that OTHER.REALM has the authority to issue tickets for the realm of the header ticket client, and adds OTHER.REALM to the transited list of the issued ticket if it does not match the realm of the header ticket client.&lt;br /&gt;
&lt;br /&gt;
If the requested server is a TGS principal for a different realm, the KDC may issue a ticket to an alternative TGS principal for an intermediate realm instead.  If the requested server is not a TGS server but the request has the &amp;quot;canonicalize&amp;quot; KDC option set ({{rfcref|6803}} section 3), the KDC may issue a ticket to an outgoing TGS principal; this is called a &amp;quot;referral&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
For local clients, some KDC implementations look up the client DB entry and apply the entry's policy in case it has changed (e.g. the account has been revoked).  The MIT krb5 KDC does not currently do this.&lt;br /&gt;
&lt;br /&gt;
It is possible for an otherwise normal TGS request to be part of a cross-realm Resource-Based Constrained Delegation (RBCD) operation transiting through this realm.  In this case, the header ticket will be a cross-realm TGT, the request server will be a cross-realm TGS, the header ticket PAC will contain an S4U_DELEGATION_INFO buffer giving the ticket client as the last transited service, and the PAC_CLIENT_INFO buffer will contain a realm part in the name.  These requests can be processed the same way as a normal TGS request, but when issuing a PAC for the resulting ticket the KDC must copy the PAC_CLIENT_INFO buffer from the header ticket rather than creating one for the ticket client.&lt;br /&gt;
&lt;br /&gt;
==Ticket modification requests==&lt;br /&gt;
&lt;br /&gt;
A ticket modification request has the forwarded, proxy, renew, or validate option.  The header ticket is not required to be a TGT, and must not be a TGT if the proxy option is requested.  The request sname must match the ticket sname, and the KDC must not be issuing a referral.  The header ticket must have a flag corresponding to the requested option (forwardable for forwarded, etc.)  The issued ticket will be similar in most respects to the header ticket, except for the addresses, validity times, and invalid flag as indicated by the request option.&lt;br /&gt;
&lt;br /&gt;
==User-to-user requests==&lt;br /&gt;
&lt;br /&gt;
If the enc-tkt-in-skey option is requested, the request must contain a second ticket in the additional-tickets field.  The second ticket must be a local-realm TGT for the server realm (krbtgt/THIS.REALM@THIS.REALM), and the second ticket cname and crealm must match the request sname and realm.  The request is processed similarly to a normal request, but the resulting ticket will be encrypted in the session key of the second ticket, and will have a session key of the same type as the second ticket's.  User-to-user requests cannot generate referrals.&lt;br /&gt;
&lt;br /&gt;
==S4U2Self (protocol transition) requests==&lt;br /&gt;
&lt;br /&gt;
If the request pa-data contains an element of type PA-FOR-USER or PA_S4U_X509_USER or both, it is a request to issue a ticket from a named user (known as the &amp;quot;subject&amp;quot;) to the requesting service.  The subject may be identified by principal or by X.509 certificate.  S4U2Self requests do not require special privileges, although in some cases the forwardable flag will be cleared on the resulting ticket.  S4U2Self requests must not contain any options for other kinds of special TGS requests (ticket modification, user-to-user, and S4U2Proxy).&lt;br /&gt;
&lt;br /&gt;
For a local-realm S4U2Self requests, the request server must match the header ticket client, although they may use different aliases for the same principal.  A PAC must be present in the header ticket, although it is not used as a basis for the PAC in the issued ticket.  The subject is looked up in the database, checked for policy constraints, and a PAC is issued for it as it would be for an AS request.  Authentication indicators are not copied from the header ticket, as there was no actual authentication of the subject.&lt;br /&gt;
&lt;br /&gt;
For cross-realm S4U2Self scenarios, there are four different kinds of requests:&lt;br /&gt;
&lt;br /&gt;
1. Zero or more AS requests to determine the subject realm, if it is not already known.  These may be ordinary AS requests, but they may also contain PA_S4U_X509_USER if the user is identified by a certificate.  The requesting service begins at the service realm and follows the chain of KDC_ERR_WRONG_REALM errors until a KDC_ERR_PREAUTH_REQUIRED error is received or a ticket is issued, indicating that the subject realm is known.  The requesting server then obtains a cross-realm TGT to the subject realm using ordinary TGS requests.&lt;br /&gt;
&lt;br /&gt;
2. A cross-realm S4U2Self request to the subject realm.  Since the requesting service does not live in this realm, the request server will contain the representation of a requesting service as an enterprise principal.  As for a local S4U2Self request, the subject realm KDC looks up the subject in the database, checks it for policy constraints, and constructs a PAC for the subject.  Unlike a local request, the PAC_CLIENT_INFO name in the PAC will contain an &amp;quot;@REALM&amp;quot; suffix identifying the subject realm, and the KDC issues a referral TGT back towards the service realm.  The reply includes PA_S4U_X509_USER naming the subject principal, in case a certificate was used to identify it.&lt;br /&gt;
&lt;br /&gt;
3. Zero or more cross-realm S4U2Self requests to intermediate realms along the path back to the service realm, each resulting in a referral TGT.  The S4U2Self padata in these requests must contain the subject principal name; the subject can no longer be identified by certificate at this step.  As in step 2, the PAC in the issued referral TGTs must be for the subject and must contain an &amp;quot;@REALM&amp;quot; suffix in the PAC_CLIENT_INFO name.&lt;br /&gt;
&lt;br /&gt;
4. A cross-realm S4U2Self request to the service realm.  This type of request would ordinarily fail the lineage check (as the client is in the local realm and the TGT was issued by another realm), so S4U2Self requests are excepted from this check.  The service realm KDC issues a ticket from the subject to the requesting service, using the PAC in the the referral ticket as a basis.  However, the PAC_CLIENT_INFO name for the PAC does not contain the &amp;quot;@REALM&amp;quot; suffix.&lt;br /&gt;
&lt;br /&gt;
S4U2Self requests override the no_authdata_required flag on the requesting service principal.  Although the service may not require authorization data for tickets received from clients, its use of S4U2Self strongly suggests the need for a PAC--either the service plans to make an S4U2Proxy request, or it has a special need to inspect the PAC for a subject.&lt;br /&gt;
&lt;br /&gt;
If the requesting service has any outgoing constrained delegation privileges, but does not have the ok_to_auth_as_delegate principal flag, then the forwardable ticket flag will be suppressed on tickets issued to it via S4U2Self.  The intent is to prevent the use of S4U2Self-issued tickets as S4U2Proxy evidence tickets without this extra privilege when outgoing authorizations are used (but not when the delegation is allowed by an incoming authorization on the delegation target).&lt;br /&gt;
&lt;br /&gt;
S4U2Self is fully specified in [http://msdn.microsoft.com/en-us/library/cc246071(PROT.13).aspx [MS-SFU]].&lt;/div&gt;</summary>
		<author><name>Ghudson</name></author>	</entry>

	<entry>
		<id>https://k5wiki.kerberos.org/wiki?title=TGS_Requests&amp;diff=6023</id>
		<title>TGS Requests</title>
		<link rel="alternate" type="text/html" href="https://k5wiki.kerberos.org/wiki?title=TGS_Requests&amp;diff=6023"/>
				<updated>2021-12-09T01:07:38Z</updated>
		
		<summary type="html">&lt;p&gt;Ghudson: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Kerberos Ticket Granting Service (TGS) requests are one of the most complicated areas of processing in MIT krb5, in both the client and the KDC.  Here are some notes on the different kind of TGS requests and what considerations must be made when processing them.&lt;br /&gt;
&lt;br /&gt;
==Protocol structure==&lt;br /&gt;
&lt;br /&gt;
Like an AS request, a TGS request contains a KDC-REQ-BODY sequence and a sequence of PA-DATA.  One of the pa-data elements will have type PA-TGS-REQ; its value will contain an AP-REQ, the same protocol structure a client would use to authenticate to an application server.  The ticket in the AP-REQ is called the &amp;quot;header ticket&amp;quot; within the MIT KDC source code, because {{rfcref|4120}} uses the term &amp;quot;authentication header&amp;quot; to refer to the AP-REQ.&lt;br /&gt;
&lt;br /&gt;
The authenticator in the AP-REQ contains a checksum over the encoding of the body.  This checksum need not be keyed, as it is contained within an encrypted payload, but with modern encryption types it is usually a keyed checksum anyway.  There is no intrinsic cryptographic binding between other padata elements and the PA-TGS-REQ or the body.&lt;br /&gt;
&lt;br /&gt;
The authenticator in the AP-REQ may contain a subkey, in which case the TGS response should be encrypted in the subkey.  Otherwise it should be encrypted in the session key of the header ticket.  There are four historical interoperability bugs affecting the use of subkeys in TGS requests, as described here:&lt;br /&gt;
&lt;br /&gt;
  https://mailarchive.ietf.org/arch/msg/krb-wg/DD8CFMuWiHJhkkoHGbjx0Z1dpKo&lt;br /&gt;
  https://mailarchive.ietf.org/arch/msg/krb-wg/4qhYxn7iovCnfsHL8wmim7-8Tq0&lt;br /&gt;
  https://mailarchive.ietf.org/arch/msg/krb-wg/hl6PvUz94IQMFadSybnjGYeBCCE&lt;br /&gt;
&lt;br /&gt;
TGS requests may use FAST implicit armor ({{rfcref|6113}} section 5.4).  In this case one of the pa-data elements will have type PA-FX-FAST and its value will contain a second copy of the TGS request encrypted in a key derived from the subkey (which must be present) and the ticket session key.&lt;br /&gt;
&lt;br /&gt;
==Types of TGS requests==&lt;br /&gt;
&lt;br /&gt;
* Normal&lt;br /&gt;
&lt;br /&gt;
* Ticket modification&lt;br /&gt;
&lt;br /&gt;
* User-to-user&lt;br /&gt;
&lt;br /&gt;
* S4U2Self (aka &amp;quot;protocol transition&amp;quot;): if the request pa-data contains an element of type PA-FOR-USER or PA_S4U_X509_USER or both, it is a request to issue a ticket from a named user to the requesting service.  S4U2Self is specified in [http://msdn.microsoft.com/en-us/library/cc246071(PROT.13).aspx [MS-SFU]].&lt;br /&gt;
&lt;br /&gt;
* S4U2Proxy (aka &amp;quot;constrained delegation&amp;quot;): if the CNAME-IN-ADDL-TICKET option is requested, the request body must contain an additional ticket (called the &amp;quot;evidence ticket&amp;quot;) from a user to the requesting service--or, for a cross-realm request, a cross-TGT containing a PAC or equivalent authorization data for a user.  If delegation is allowed to the requested server, the KDC issues a ticket from the evidence ticket client (or the client named in the PAC) to the requested server.  S4U2Proxy is specified in the same document as S4U2Self.&lt;br /&gt;
&lt;br /&gt;
==Normal TGS requests==&lt;br /&gt;
&lt;br /&gt;
For the purposes of this article, a TGS request is considered &amp;quot;normal&amp;quot; if it:&lt;br /&gt;
&lt;br /&gt;
* does not have any of the forwarded, proxy, renew, validate, enc-tkt-in-skey, or cname-in-addl-tkt options&lt;br /&gt;
* does not contain PA-FOR-USER or PA_S4U_X509_USER pa-data.&lt;br /&gt;
&lt;br /&gt;
The header ticket for a normal TGS request server have an sname field of krbtgt/THIS.REALM, where THIS.REALM must match the realm field of the TGS request.  If the header ticket is a cross-realm TGT (the ticket's srealm field is some OTHER.REALM different from THIS.REALM), the ticket's crealm must also be different from THIS.REALM; this is called the &amp;quot;lineage check&amp;quot;, and ensures that foreign realms cannot issue tickets for local users.  The KDC also (unless requested not to) checks the transited list in the ticket to ensure that OTHER.REALM has the authority to issue tickets for the realm of the header ticket client, and adds OTHER.REALM to the transited list of the issued ticket if it does not match the realm of the header ticket client.&lt;br /&gt;
&lt;br /&gt;
If the requested server is a TGS principal for a different realm, the KDC may issue a ticket to an alternative TGS principal for an intermediate realm instead.  If the requested server is not a TGS server but the request has the &amp;quot;canonicalize&amp;quot; KDC option set ({{rfcref|6803}} section 3), the KDC may issue a ticket to an outgoing TGS principal; this is called a &amp;quot;referral&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
For local clients, some KDC implementations look up the client DB entry and apply the entry's policy in case it has changed (e.g. the account has been revoked).  The MIT krb5 KDC does not currently do this.&lt;br /&gt;
&lt;br /&gt;
It is possible for an otherwise normal TGS request to be part of a cross-realm Resource-Based Constrained Delegation (RBCD) operation transiting through this realm.  In this case, the header ticket will be a cross-realm TGT, the request server will be a cross-realm TGS, the header ticket PAC will contain an S4U_DELEGATION_INFO buffer giving the ticket client as the last transited service, and the PAC_CLIENT_INFO buffer will contain a realm part in the name.  These requests can be processed the same way as a normal TGS request, but when issuing a PAC for the resulting ticket the KDC must copy the PAC_CLIENT_INFO buffer from the header ticket rather than creating one for the ticket client.&lt;br /&gt;
&lt;br /&gt;
==Ticket modification requests==&lt;br /&gt;
&lt;br /&gt;
A ticket modification request has the forwarded, proxy, renew, or validate option.  The header ticket is not required to be a TGT, and must not be a TGT if the proxy option is requested.  The request sname must match the ticket sname, and the KDC must not be issuing a referral.  The header ticket must have a flag corresponding to the requested option (forwardable for forwarded, etc.)  The issued ticket will be similar in most respects to the header ticket, except for the addresses, validity times, and invalid flag as indicated by the request option.&lt;br /&gt;
&lt;br /&gt;
==User-to-user requests==&lt;br /&gt;
&lt;br /&gt;
If the enc-tkt-in-skey option is requested, the request must contain a second ticket in the additional-tickets field.  The second ticket must be a local-realm TGT for the server realm (krbtgt/THIS.REALM@THIS.REALM), and the second ticket cname and crealm must match the request sname and realm.  The request is processed similarly to a normal request, but the resulting ticket will be encrypted in the session key of the second ticket, and will have a session key of the same type as the second ticket's.  User-to-user requests cannot generate referrals.&lt;/div&gt;</summary>
		<author><name>Ghudson</name></author>	</entry>

	<entry>
		<id>https://k5wiki.kerberos.org/wiki?title=TGS_Requests&amp;diff=6022</id>
		<title>TGS Requests</title>
		<link rel="alternate" type="text/html" href="https://k5wiki.kerberos.org/wiki?title=TGS_Requests&amp;diff=6022"/>
				<updated>2021-12-09T00:45:49Z</updated>
		
		<summary type="html">&lt;p&gt;Ghudson: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Kerberos Ticket Granting Service (TGS) requests are one of the most complicated areas of processing in MIT krb5, in both the client and the KDC.  Here are some notes on the different kind of TGS requests and what considerations must be made when processing them.&lt;br /&gt;
&lt;br /&gt;
==Protocol structure==&lt;br /&gt;
&lt;br /&gt;
Like an AS request, a TGS request contains a KDC-REQ-BODY sequence and a sequence of PA-DATA.  One of the pa-data elements will have type PA-TGS-REQ; its value will contain an AP-REQ, the same protocol structure a client would use to authenticate to an application server.  The ticket in the AP-REQ is called the &amp;quot;header ticket&amp;quot; within the MIT KDC source code, because {{rfcref|4120}} uses the term &amp;quot;authentication header&amp;quot; to refer to the AP-REQ.&lt;br /&gt;
&lt;br /&gt;
The authenticator in the AP-REQ contains a checksum over the encoding of the body.  This checksum need not be keyed, as it is contained within an encrypted payload, but with modern encryption types it is usually a keyed checksum anyway.  There is no intrinsic cryptographic binding between other padata elements and the PA-TGS-REQ or the body.&lt;br /&gt;
&lt;br /&gt;
The authenticator in the AP-REQ may contain a subkey, in which case the TGS response should be encrypted in the subkey.  Otherwise it should be encrypted in the session key of the header ticket.  There are four historical interoperability bugs affecting the use of subkeys in TGS requests, as described here:&lt;br /&gt;
&lt;br /&gt;
  https://mailarchive.ietf.org/arch/msg/krb-wg/DD8CFMuWiHJhkkoHGbjx0Z1dpKo&lt;br /&gt;
  https://mailarchive.ietf.org/arch/msg/krb-wg/4qhYxn7iovCnfsHL8wmim7-8Tq0&lt;br /&gt;
  https://mailarchive.ietf.org/arch/msg/krb-wg/hl6PvUz94IQMFadSybnjGYeBCCE&lt;br /&gt;
&lt;br /&gt;
TGS requests may use FAST implicit armor ({{rfcref|6113}} section 5.4).  In this case one of the pa-data elements will have type PA-FX-FAST and its value will contain a second copy of the TGS request encrypted in a key derived from the subkey (which must be present) and the ticket session key.&lt;br /&gt;
&lt;br /&gt;
==Types of TGS requests==&lt;br /&gt;
&lt;br /&gt;
* Normal&lt;br /&gt;
&lt;br /&gt;
* Ticket modification: if the RENEW, VALIDATE, or PROXY option is requested, the header ticket server need not be a TGT (and must not be a TGT for PROXY), but the requested server must match the header ticket server.  The RENEW option is frequently used in practice, while the VALIDATE and PROXY options are not.&lt;br /&gt;
&lt;br /&gt;
* User-to-user: if the ENC-TKT-IN-SKEY option is requested, the request body must contain an additional ticket, whose client must match the requested server and whose server must be the local TGS (krbtgt/THIS.REALM@THIS.REALM).  The issued ticket will be encrypted in the session key of the second ticket, not in the long-term key of the service principal.&lt;br /&gt;
&lt;br /&gt;
* S4U2Self (aka &amp;quot;protocol transition&amp;quot;): if the request pa-data contains an element of type PA-FOR-USER or PA_S4U_X509_USER or both, it is a request to issue a ticket from a named user to the requesting service.  S4U2Self is specified in [http://msdn.microsoft.com/en-us/library/cc246071(PROT.13).aspx [MS-SFU]].&lt;br /&gt;
&lt;br /&gt;
* S4U2Proxy (aka &amp;quot;constrained delegation&amp;quot;): if the CNAME-IN-ADDL-TICKET option is requested, the request body must contain an additional ticket (called the &amp;quot;evidence ticket&amp;quot;) from a user to the requesting service--or, for a cross-realm request, a cross-TGT containing a PAC or equivalent authorization data for a user.  If delegation is allowed to the requested server, the KDC issues a ticket from the evidence ticket client (or the client named in the PAC) to the requested server.  S4U2Proxy is specified in the same document as S4U2Self.&lt;br /&gt;
&lt;br /&gt;
==Normal TGS requests==&lt;br /&gt;
&lt;br /&gt;
For the purposes of this article, a TGS request is considered &amp;quot;normal&amp;quot; if it:&lt;br /&gt;
&lt;br /&gt;
* does not have any of the forwarded, proxy, renew, validate, enc-tkt-in-skey, or cname-in-addl-tkt options&lt;br /&gt;
* does not contain PA-FOR-USER or PA_S4U_X509_USER pa-data.&lt;br /&gt;
&lt;br /&gt;
The header ticket for a normal TGS request server must be a TGT, meaning its sname field is krbtgt/THIS.REALM.  If it is a cross-realm TGT (the srealm field is some OTHER.REALM different from THIS.REALM), the ticket's crealm must also be different from THIS.REALM; this is called the &amp;quot;lineage check&amp;quot;, and ensures that foreign realms cannot issue tickets for local users.  The KDC also (unless requested not to) checks the transited list in the ticket to ensure that OTHER.REALM has the authority to issue tickets for the realm of the header ticket client, and adds OTHER.REALM to the transited list of the issued ticket if it does not match the realm of the header ticket client.&lt;br /&gt;
&lt;br /&gt;
If the requested server is a TGS principal for a different realm, the KDC may issue a ticket to an alternative TGS principal for an intermediate realm instead.  If the requested server is not a TGS server but the request has the &amp;quot;canonicalize&amp;quot; KDC option set ({{rfcref|6803}} section 3), the KDC may issue a ticket to an outgoing TGS principal; this is called a &amp;quot;referral&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
For local clients, some KDC implementations look up the client DB entry and apply the entry's policy in case it has changed (e.g. the account has been revoked).  The MIT krb5 KDC does not currently do this.&lt;br /&gt;
&lt;br /&gt;
It is possible for an otherwise normal TGS request to be part of a cross-realm Resource-Based Constrained Delegation (RBCD) operation transiting through this realm.  In this case, the header ticket will be a cross-realm TGT, the request server will be a cross-realm TGS, the header ticket PAC will contain an S4U_DELEGATION_INFO buffer giving the ticket client as the last transited service, and the PAC_CLIENT_INFO buffer will contain a realm part in the name.  These requests can be processed the same way as a normal TGS request, but when issuing a PAC for the resulting TGT the KDC must copy the PAC_CLIENT_INFO values from the header ticket rather than issuing one for the ticket client.&lt;/div&gt;</summary>
		<author><name>Ghudson</name></author>	</entry>

	<entry>
		<id>https://k5wiki.kerberos.org/wiki?title=Kerberos.org_server_configuration&amp;diff=6021</id>
		<title>Kerberos.org server configuration</title>
		<link rel="alternate" type="text/html" href="https://k5wiki.kerberos.org/wiki?title=Kerberos.org_server_configuration&amp;diff=6021"/>
				<updated>2021-08-06T16:40:35Z</updated>
		
		<summary type="html">&lt;p&gt;Ghudson: /* BIND configuration */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page documents the service configuration on kerberos.org (current canonical name kerborg-prod-app-2.mit.edu), which runs a web server, a wiki, and a DNS name server.&lt;br /&gt;
&lt;br /&gt;
==Packages==&lt;br /&gt;
&lt;br /&gt;
The apache2, bind9, certbot, mediawiki, and python3-certbot-apache packages are required.&lt;br /&gt;
&lt;br /&gt;
==Web server configuration==&lt;br /&gt;
&lt;br /&gt;
The static web page content is located in /var/www.&lt;br /&gt;
&lt;br /&gt;
The Apache HTTP server configuration can be found in the krbdev-services repository under kerborg-apache.  kerborg.cnf should be installed in /etc/ssl/private; the rest go in /etc/apache2/sites-available.  Run the following commands to enable the correct configuration files:&lt;br /&gt;
&lt;br /&gt;
  a2ensite 000-default-kerberos-org.conf&lt;br /&gt;
  a2ensite k5wiki.conf&lt;br /&gt;
  a2dissite 000-default.conf&lt;br /&gt;
  a2enmod rewrite&lt;br /&gt;
  a2enmod ssl&lt;br /&gt;
&lt;br /&gt;
The letsencrypt TLS certificate is generated using certbot:&lt;br /&gt;
&lt;br /&gt;
  certbot --apache -d 'kerberos.org,www.kerberos.org,k5wiki.kerberos.org,test.kerberos.org,www.test.kerberos.org,k5wiki.test.kerberos.org,kerberos.net,www.kerberos.net' certonly&lt;br /&gt;
&lt;br /&gt;
letsencrypt certificates only last 90 days, but a systemd timer installed by the certbot package will automatically renew the certificate when it approaches expiration.&lt;br /&gt;
&lt;br /&gt;
==Mediawiki configuration==&lt;br /&gt;
&lt;br /&gt;
/etc/mediawiki/LocalSettings.php and /etc/mediawiki/Secrets.php contain the wiki configuration.  Secrets.php must be readable by the web server; this is currently enabled by making it more 640 and owned by group www-data.&lt;br /&gt;
&lt;br /&gt;
The wiki contents are stored in a MySQL database named &amp;quot;wikidb&amp;quot;.  This can be dumped with &amp;quot;mysqldump --databases wikidb &amp;gt; /somepath&amp;quot; and loaded with &amp;quot;mysql &amp;lt; /somepath&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
A MySQL user named &amp;quot;wikiuser&amp;quot; must be created to access the database.  To create it run the following commands inside mysql:&lt;br /&gt;
&lt;br /&gt;
  create user wikiuser@localhost identified by '&amp;lt;password&amp;gt;';&lt;br /&gt;
  grant all privileges on `wikidb`.* to 'wikiuser'@'localhost';&lt;br /&gt;
&lt;br /&gt;
Use the password from /etc/mediawiki/Secrets.php.&lt;br /&gt;
&lt;br /&gt;
If migrating to a server with a new version of Mediawiki, the database must be upgraded.  Navigate to /wm-config on the new server and follow instructions.&lt;br /&gt;
&lt;br /&gt;
==Database backups==&lt;br /&gt;
&lt;br /&gt;
Install /mit/ops/services/mysql/mysqlbackup_java.sh in /usr/local/sbin and make it mode 755.  Modify the script to use /bin/bzip2 instead of /usr/bin/bzip2, and delete the three java invocations (which are for monitoring).&lt;br /&gt;
&lt;br /&gt;
/usr/local/etc/mysqlbackup_java.conf contains the database password (PASS=xxxxx) and specifies COMPRESS=yes.  Make it mode 600.&lt;br /&gt;
&lt;br /&gt;
Create a MySQL user for backups by running the following within mysql:&lt;br /&gt;
&lt;br /&gt;
  create user 'dba-backup'@localhost identified by '&amp;lt;password&amp;gt;';&lt;br /&gt;
  grant select, process, file, lock tables, show view on *.* to 'dba-backup'@'localhost;&lt;br /&gt;
&lt;br /&gt;
Add the following root cron job:&lt;br /&gt;
&lt;br /&gt;
  00 23 * * * /usr/local/sbin/mysqlbackup_java.sh &amp;gt;/dev/null 2&amp;gt;&amp;amp;1&lt;br /&gt;
&lt;br /&gt;
==BIND configuration==&lt;br /&gt;
&lt;br /&gt;
The bind9 configuration files can be found in krbdev-services under bind.  They should be installed under /etc/bind.  &amp;quot;rndc reload&amp;quot; will restart the runing named with the changed configuration.  If it is necessary to edit any of the zone files, be sure to update the serial number in the SOA record to the current date followed by &amp;quot;00&amp;quot; (or &amp;quot;01&amp;quot; etc. for successive edits in the same day).&lt;br /&gt;
&lt;br /&gt;
If the IP address if kerberos.org needs to be changed, the glue record at hover.com must be updated.  In the current Hover UI, glue records can be found under &amp;quot;advanced&amp;quot;.  The transfer lock on the domain must be temporarily disabled (via the Overview screen) to update glue records.  Make sure to edit the records for kerberos.net as well as kerberos.org.&lt;/div&gt;</summary>
		<author><name>Ghudson</name></author>	</entry>

	<entry>
		<id>https://k5wiki.kerberos.org/wiki?title=RT_server_configuration&amp;diff=6020</id>
		<title>RT server configuration</title>
		<link rel="alternate" type="text/html" href="https://k5wiki.kerberos.org/wiki?title=RT_server_configuration&amp;diff=6020"/>
				<updated>2021-06-01T23:52:38Z</updated>
		
		<summary type="html">&lt;p&gt;Ghudson: /* Testing */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page contains notes on the setup of the MIT krb5 RT server. The current server is krbdev.mit.edu (canonical name kerborg-prod-app-1.mit.edu), which runs Ubuntu 20.04.&lt;br /&gt;
&lt;br /&gt;
==Packages==&lt;br /&gt;
&lt;br /&gt;
In Ubuntu 20.04, the request-tracker4 package contains a suitable version of RT.  This package will ask some questions at installation time:&lt;br /&gt;
&lt;br /&gt;
* RT site name: krbdev.mit.edu&lt;br /&gt;
* handle RT_SiteConfig.pm permissions: yes&lt;br /&gt;
* use dbconfig-common: no&lt;br /&gt;
&lt;br /&gt;
The data in RT is stored in a PostgreSQL database.  The postgresql Ubuntu package will install the recommended version of PostgreSQL for the current Ubuntu version.&lt;br /&gt;
&lt;br /&gt;
The mail interface to RT is handled by Postfix, so the postfix package is required.  The libsendmail-pmilter-perl package is required for the custom milter script.&lt;br /&gt;
&lt;br /&gt;
The web front end to RT is an Apache2 web server, so the apache2 package is required.  RT uses a FastCGI server, so the libapache2-mod-fcgid package is required.&lt;br /&gt;
&lt;br /&gt;
The server host acts as an authoritative name server for the kerberos.org zone, so the bind9 package must be installed.&lt;br /&gt;
&lt;br /&gt;
In sum, the following packages must be installed on the RT server:&lt;br /&gt;
&lt;br /&gt;
  apache2&lt;br /&gt;
  bind9&lt;br /&gt;
  libapache2-mod-fcgid&lt;br /&gt;
  libsendmail-pmilter-perl&lt;br /&gt;
  perl&lt;br /&gt;
  perl-base&lt;br /&gt;
  postfix&lt;br /&gt;
  postgresql&lt;br /&gt;
  request-tracker4&lt;br /&gt;
&lt;br /&gt;
==User accounts==&lt;br /&gt;
&lt;br /&gt;
The postgresql package will create a postgres user account.&lt;br /&gt;
&lt;br /&gt;
The following user accounts and group entries must be created manually:&lt;br /&gt;
&lt;br /&gt;
* group rt&lt;br /&gt;
* user rtcvs: primary group rt, homedir /var/rt2, shell /bin/sh&lt;br /&gt;
* user rt: primary group rt, homedir /var/rt2, shell /bin/false&lt;br /&gt;
&lt;br /&gt;
These accounts could be created with:&lt;br /&gt;
&lt;br /&gt;
  groupadd -r rt&lt;br /&gt;
  useradd -r -g rt -d /var/rt2 rtcvs&lt;br /&gt;
  useradd -r -m -g rt -d /var/rt2 -s /bin/false rt&lt;br /&gt;
&lt;br /&gt;
Some of the above accounts may be created by ops during provisioning.  /var/rt2 and /var/rt2/.ssh must be owned by rtcvs or sshd will reject logins as rtcvs from drugstore.&lt;br /&gt;
&lt;br /&gt;
Create /var/rt2/bin and copy in the following scripts from the krbdev-services repository:&lt;br /&gt;
&lt;br /&gt;
  rt-scripts/rt-reserve-ticket&lt;br /&gt;
  rt-scripts/rtmilter.pl&lt;br /&gt;
  rt-scripts/krb5-daily.sh&lt;br /&gt;
  rt-cvs/rt-cvsgate&lt;br /&gt;
&lt;br /&gt;
The scripts and directory should be mode 755 and owned by user rt and group rt.&lt;br /&gt;
&lt;br /&gt;
/var/rt2 should contain an empty .k5login file, managed by ops.  It should contain a .ssh/authorized_keys file, managed by ops, containing the krbsnap key from /git/krb5.git/hooks/krbsnap_rsa_key.pub on drugstore.mit.edu.&lt;br /&gt;
&lt;br /&gt;
Create /var/psqlbackups (owned by root).&lt;br /&gt;
&lt;br /&gt;
The rt user account is not actually needed for the current RT installation, and the homedir name /var/rt2 is outdated.  The following references need to be taken into account when changing the user and group configuration:&lt;br /&gt;
&lt;br /&gt;
* Both the rt and rtcvs accounts have the homedir /var/rt2.&lt;br /&gt;
* krb5-daily.sh references the krbsnap.keytab file and dumps directory in /var/rt2.&lt;br /&gt;
* A root cron job runs krb5-daily.sh from /var/rt2.&lt;br /&gt;
* A root cron job runs rtmilter on boot from /var/rt2.&lt;br /&gt;
* The empty /var/rt2/.k5login file is managed by ops.&lt;br /&gt;
* The /var/rt2/.ssh/authorized_keys file is managed by ops.&lt;br /&gt;
* On drugstore.mit.edu, the krb5 git repository rt-ssh-cmd config value references the rtcvs user and /var/rt2/bin/rt-cvsgate.&lt;br /&gt;
* On drugstore.mit.edu, the krb5 git repository hooks/krb5-rt-id script references the rtcvs user and /var/rt2/bin/rt-reserve-ticket.  This script comes from the krbdev-services repository's githooks/krb5-rt-id.&lt;br /&gt;
* Some of the same references are present in the krbdev-services repository, but they aren't used.&lt;br /&gt;
&lt;br /&gt;
==RT setup==&lt;br /&gt;
&lt;br /&gt;
Install the RT_SiteConfig.pm file from the krbdev-services repository in /etc/request-tracker4.&lt;br /&gt;
&lt;br /&gt;
In root's crontab file (&amp;quot;crontab -e&amp;quot; as root), add the following to perform daily maintenance:&lt;br /&gt;
&lt;br /&gt;
  MAILTO=krbcore-hw@mit.edu&lt;br /&gt;
  0 3 * * * /usr/sbin/rt-clean-sessions&lt;br /&gt;
  0 4 * * * /var/rt2/bin/krb5-daily.sh&lt;br /&gt;
&lt;br /&gt;
==PostgreSQL configuration==&lt;br /&gt;
&lt;br /&gt;
Many PostgreSQL files live in directories specific to the PostgreSQL major and minor version, such as /etc/postgresql/8.3 for PostgreSQL 8.3.&lt;br /&gt;
&lt;br /&gt;
The Ubuntu postgresql package will create a &amp;quot;main&amp;quot; cluster with a configuration directory in /etc/postgresql/&amp;lt;version&amp;gt;/main.&lt;br /&gt;
&lt;br /&gt;
In /etc/postgresql/&amp;lt;version&amp;gt;/main/pg_ident.conf, add:&lt;br /&gt;
&lt;br /&gt;
  local		root		root&lt;br /&gt;
  local		root		postgres&lt;br /&gt;
  local		root		rt_user&lt;br /&gt;
  local		rt		rt_user&lt;br /&gt;
  local		rtcvs		rt_user&lt;br /&gt;
  local		postfix		rt_user&lt;br /&gt;
  local		nobody		rt_user&lt;br /&gt;
  local         www-data        rt_user&lt;br /&gt;
&lt;br /&gt;
(The entry for &amp;quot;rt&amp;quot; should no longer be needed, but is currently still present.)&lt;br /&gt;
&lt;br /&gt;
In /etc/postgresql/&amp;lt;version&amp;gt;/main/pg_hba.conf, find the line that reads &amp;quot;local all all peer&amp;quot; and add &amp;quot;map=local&amp;quot; to the end, so it reads &amp;quot;local all all peer map=local&amp;quot;.  Comment out the line that reads &amp;quot;local all postgres peer&amp;quot;, despite the warning not to disable it.  Run &amp;quot;service postgresql restart&amp;quot; to reread the affected files.  Run &amp;quot;psql -Upostgres --list&amp;quot; to verify that the identity map works.&lt;br /&gt;
&lt;br /&gt;
Run &amp;quot;createuser -Upostgres rt_user&amp;quot; to create the rt_user role.&lt;br /&gt;
&lt;br /&gt;
Run &amp;quot;/usr/sbin/rt-setup-database --action create&amp;quot; to create the database, then restore it from a backup with &amp;quot;zcat /path/to/dump.gz | psql -d rt4 -Upostgres&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==Postfix configuration==&lt;br /&gt;
&lt;br /&gt;
By default ops manages Postfix with Puppet.  This must be disabled by ops, and the Debian defaults restored by copying /usr/share/postfix/main.cf.debian to /etc/postfix/main.cf and /usr/share/postfix/master.cf.dist to /etc/postfix/master.cf.&lt;br /&gt;
&lt;br /&gt;
At the end of /etc/postfix/main.cf add:&lt;br /&gt;
&lt;br /&gt;
  myhostname = krbdev.mit.edu&lt;br /&gt;
  mydestination = krbdev.mit.edu, kerborg-prod-app-1.mit.edu, localhost.mit.edu, localhost&lt;br /&gt;
  &lt;br /&gt;
  # Suppress some headers to avoid leaking internal addresses to spammers.&lt;br /&gt;
  prepend_delivered_header =&lt;br /&gt;
  enable_original_recipient = no&lt;br /&gt;
  &lt;br /&gt;
  # RT header milter&lt;br /&gt;
  smtpd_milters = unix:private/milter&lt;br /&gt;
&lt;br /&gt;
Copy /etc/aliases from the old server.  To avoid aiding spammers, its contents are not reproduced here.  In particular, /etc/aliases contains an internal address corresponding to the membership of the krb5-bugs-incoming mailman list; revealing this address could allow spammers to bypass moderation of incoming bug reports.&lt;br /&gt;
&lt;br /&gt;
In root's crontab file (&amp;quot;crontab -e&amp;quot; as root):&lt;br /&gt;
&lt;br /&gt;
  @reboot /var/rt2/bin/rtmilter.pl /var/spool/postfix/private/milter&lt;br /&gt;
&lt;br /&gt;
Run the command by hand (backgrounded) to start the milter process before the next reboot.&lt;br /&gt;
&lt;br /&gt;
Run &amp;quot;newaliases&amp;quot; and &amp;quot;postfix reload&amp;quot; to pick up the changed configuration.&lt;br /&gt;
&lt;br /&gt;
Make sure rt@kerborg-prod-app-1.mit.edu and rt-comment@kerborg-prod-app-1.mit.edu are authorized as non-member senders at https://mailman.mit.edu:444/mailman/admin/krb5-bugs/privacy/sender .&lt;br /&gt;
&lt;br /&gt;
==Apache httpd configuration==&lt;br /&gt;
&lt;br /&gt;
Create /etc/apache2/ssl.crt and /etc/apache2/ssl.key.&lt;br /&gt;
&lt;br /&gt;
Copy /etc/apache2/ssl.key/server.key and /etc/apache2/ssl.crt/server.crt from the old server, or follow the instructions at http://kb.mit.edu/confluence/display/istcontrib/Obtaining+an+SSL+certificate+for+a+web+server to obtain a new one.  server.key and server.crt may be symlinks using whatever scheme seems convenient for renewing certificates every few years.&lt;br /&gt;
&lt;br /&gt;
Install /etc/apache2/ssl.crt/chain.crt from /mit/apache-ssl/certificates/InCommon-chain.crt.txt (requires tokens).  Cutting and pasting is effective for transferring certificates as they are represented as short text files.&lt;br /&gt;
&lt;br /&gt;
Install /etc/apache2/ssl.crt/clientCA.crt from /mit/apache-ssl/certificates/mitCAclient.pem (requires tokens).&lt;br /&gt;
&lt;br /&gt;
Install the rt.conf file from the krbdev-services repository as /etc/apache2/sites-available/rt.conf .&lt;br /&gt;
&lt;br /&gt;
Edit /etc/apache2/mods-available/proxy.conf and set:&lt;br /&gt;
&lt;br /&gt;
  ProxyVia On&lt;br /&gt;
&lt;br /&gt;
  ProxyPass /buildbot/ws ws://krbdev-buildbot.mit.edu:8010/ws&lt;br /&gt;
  ProxyPassReverse /buildbos/ws ws://krbdev-buildbot.mit.edu:8010/ws&lt;br /&gt;
  ProxyPass /buildbot/ http://krbdev-buildbot.mit.edu:8010/&lt;br /&gt;
  ProxyPassReverse /buildbot/ http://krbdev-buildbot.mit.edu:8010/&lt;br /&gt;
  &amp;lt;Proxy http://krbdev-buildbot.mit.edu:8010/*&amp;gt;&lt;br /&gt;
          Allow from all&lt;br /&gt;
  &amp;lt;/Proxy&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Edit /etc/apache2/ports.conf and add &amp;quot;Listen 444&amp;quot; in the ssl_module section after &amp;quot;Listen 443&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Clean out /var/www and install index.html and robots.txt from the krbdev-www directory of the krbdev-services repository.&lt;br /&gt;
&lt;br /&gt;
Run:&lt;br /&gt;
&lt;br /&gt;
  a2enmod ssl&lt;br /&gt;
  a2enmod userdir&lt;br /&gt;
  a2enmod rewrite&lt;br /&gt;
  a2enmod proxy_http&lt;br /&gt;
  a2enmod proxy_wstunnel&lt;br /&gt;
  a2dissite 000-default&lt;br /&gt;
  a2ensite rt&lt;br /&gt;
  service apache2 restart&lt;br /&gt;
&lt;br /&gt;
==Testing==&lt;br /&gt;
&lt;br /&gt;
Get a certificate for the new VM's real hostname and temporarily point /etc/apache2/ssl.crt/server.crt at it.&lt;br /&gt;
&lt;br /&gt;
In /etc/request-tracker4/RT_SiteConfig.pm, temporarily set @ReferrerWhitelist to use the real hostname instead of krbdev.mit.edu.&lt;br /&gt;
&lt;br /&gt;
Temporarily set emergency moderation on the krb5-bugs mailing list (at https://mailman.mit.edu:444/mailman/admin/krb5-bugs/general ) to ensure that mail sent to that list as the result of testing is caught in the moderation queue.&lt;br /&gt;
&lt;br /&gt;
Verify that RT displays at https://realhostname/rt and tickets can be accessed.  Verify that https://realhostname:444/ works and that a new ticket can be created.  Respond to the ticket via email and verify that the response is stored in the ticket.&lt;br /&gt;
&lt;br /&gt;
As root, run /var/rt2/bin/krb5-daily.sh and verify that a dump file appears in /var/psqlbackups.&lt;br /&gt;
&lt;br /&gt;
As rtcvs (&amp;quot;su -s /bin/bash - rtcvs&amp;quot;), run /var/rt2/bin/rt-reserve-ticket and verify that a ticket number is printed.&lt;br /&gt;
&lt;br /&gt;
To test rt-cvsgate, create a test message in /tmp/testmsg like so:&lt;br /&gt;
&lt;br /&gt;
  ticket: new&lt;br /&gt;
  id: NNNN (use the ticket number printed by rt-reserve-ticket above)&lt;br /&gt;
  subject: rt-cvsgate test&lt;br /&gt;
  tags: pullup&lt;br /&gt;
&lt;br /&gt;
  test commit message&lt;br /&gt;
&lt;br /&gt;
As rtcvs, run &amp;quot;/var/rt2/bin/rt-cvsgate ''username'' &amp;lt; /tmp/testmsg&amp;quot;, where ''username'' is an authorized user.&lt;br /&gt;
&lt;br /&gt;
Undo the temporary changes and restore the database from a dump file.&lt;br /&gt;
&lt;br /&gt;
==BIND configuration==&lt;br /&gt;
&lt;br /&gt;
The bind9 configuration files can be found in krbdev-services under bind. They should be installed under /etc/bind. &amp;quot;rndc reload&amp;quot; will restart the runing named with the changed configuration. If it is necessary to edit any of the zone files, be sure to update the serial number in the SOA record to the current date followed by &amp;quot;00&amp;quot; (or &amp;quot;01&amp;quot; etc. for successive edits in the same day).&lt;br /&gt;
&lt;br /&gt;
If the IP address if kerberos.org needs to be changed, the glue record at hover.com must be updated. In the current Hover UI, glue records can be found under &amp;quot;advanced&amp;quot;. The transfer lock on the domain must be temporarily disabled (via the Overview screen) to update glue records.&lt;/div&gt;</summary>
		<author><name>Ghudson</name></author>	</entry>

	<entry>
		<id>https://k5wiki.kerberos.org/wiki?title=RT_server_configuration&amp;diff=6019</id>
		<title>RT server configuration</title>
		<link rel="alternate" type="text/html" href="https://k5wiki.kerberos.org/wiki?title=RT_server_configuration&amp;diff=6019"/>
				<updated>2021-06-01T23:44:06Z</updated>
		
		<summary type="html">&lt;p&gt;Ghudson: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page contains notes on the setup of the MIT krb5 RT server. The current server is krbdev.mit.edu (canonical name kerborg-prod-app-1.mit.edu), which runs Ubuntu 20.04.&lt;br /&gt;
&lt;br /&gt;
==Packages==&lt;br /&gt;
&lt;br /&gt;
In Ubuntu 20.04, the request-tracker4 package contains a suitable version of RT.  This package will ask some questions at installation time:&lt;br /&gt;
&lt;br /&gt;
* RT site name: krbdev.mit.edu&lt;br /&gt;
* handle RT_SiteConfig.pm permissions: yes&lt;br /&gt;
* use dbconfig-common: no&lt;br /&gt;
&lt;br /&gt;
The data in RT is stored in a PostgreSQL database.  The postgresql Ubuntu package will install the recommended version of PostgreSQL for the current Ubuntu version.&lt;br /&gt;
&lt;br /&gt;
The mail interface to RT is handled by Postfix, so the postfix package is required.  The libsendmail-pmilter-perl package is required for the custom milter script.&lt;br /&gt;
&lt;br /&gt;
The web front end to RT is an Apache2 web server, so the apache2 package is required.  RT uses a FastCGI server, so the libapache2-mod-fcgid package is required.&lt;br /&gt;
&lt;br /&gt;
The server host acts as an authoritative name server for the kerberos.org zone, so the bind9 package must be installed.&lt;br /&gt;
&lt;br /&gt;
In sum, the following packages must be installed on the RT server:&lt;br /&gt;
&lt;br /&gt;
  apache2&lt;br /&gt;
  bind9&lt;br /&gt;
  libapache2-mod-fcgid&lt;br /&gt;
  libsendmail-pmilter-perl&lt;br /&gt;
  perl&lt;br /&gt;
  perl-base&lt;br /&gt;
  postfix&lt;br /&gt;
  postgresql&lt;br /&gt;
  request-tracker4&lt;br /&gt;
&lt;br /&gt;
==User accounts==&lt;br /&gt;
&lt;br /&gt;
The postgresql package will create a postgres user account.&lt;br /&gt;
&lt;br /&gt;
The following user accounts and group entries must be created manually:&lt;br /&gt;
&lt;br /&gt;
* group rt&lt;br /&gt;
* user rtcvs: primary group rt, homedir /var/rt2, shell /bin/sh&lt;br /&gt;
* user rt: primary group rt, homedir /var/rt2, shell /bin/false&lt;br /&gt;
&lt;br /&gt;
These accounts could be created with:&lt;br /&gt;
&lt;br /&gt;
  groupadd -r rt&lt;br /&gt;
  useradd -r -g rt -d /var/rt2 rtcvs&lt;br /&gt;
  useradd -r -m -g rt -d /var/rt2 -s /bin/false rt&lt;br /&gt;
&lt;br /&gt;
Some of the above accounts may be created by ops during provisioning.  /var/rt2 and /var/rt2/.ssh must be owned by rtcvs or sshd will reject logins as rtcvs from drugstore.&lt;br /&gt;
&lt;br /&gt;
Create /var/rt2/bin and copy in the following scripts from the krbdev-services repository:&lt;br /&gt;
&lt;br /&gt;
  rt-scripts/rt-reserve-ticket&lt;br /&gt;
  rt-scripts/rtmilter.pl&lt;br /&gt;
  rt-scripts/krb5-daily.sh&lt;br /&gt;
  rt-cvs/rt-cvsgate&lt;br /&gt;
&lt;br /&gt;
The scripts and directory should be mode 755 and owned by user rt and group rt.&lt;br /&gt;
&lt;br /&gt;
/var/rt2 should contain an empty .k5login file, managed by ops.  It should contain a .ssh/authorized_keys file, managed by ops, containing the krbsnap key from /git/krb5.git/hooks/krbsnap_rsa_key.pub on drugstore.mit.edu.&lt;br /&gt;
&lt;br /&gt;
Create /var/psqlbackups (owned by root).&lt;br /&gt;
&lt;br /&gt;
The rt user account is not actually needed for the current RT installation, and the homedir name /var/rt2 is outdated.  The following references need to be taken into account when changing the user and group configuration:&lt;br /&gt;
&lt;br /&gt;
* Both the rt and rtcvs accounts have the homedir /var/rt2.&lt;br /&gt;
* krb5-daily.sh references the krbsnap.keytab file and dumps directory in /var/rt2.&lt;br /&gt;
* A root cron job runs krb5-daily.sh from /var/rt2.&lt;br /&gt;
* A root cron job runs rtmilter on boot from /var/rt2.&lt;br /&gt;
* The empty /var/rt2/.k5login file is managed by ops.&lt;br /&gt;
* The /var/rt2/.ssh/authorized_keys file is managed by ops.&lt;br /&gt;
* On drugstore.mit.edu, the krb5 git repository rt-ssh-cmd config value references the rtcvs user and /var/rt2/bin/rt-cvsgate.&lt;br /&gt;
* On drugstore.mit.edu, the krb5 git repository hooks/krb5-rt-id script references the rtcvs user and /var/rt2/bin/rt-reserve-ticket.  This script comes from the krbdev-services repository's githooks/krb5-rt-id.&lt;br /&gt;
* Some of the same references are present in the krbdev-services repository, but they aren't used.&lt;br /&gt;
&lt;br /&gt;
==RT setup==&lt;br /&gt;
&lt;br /&gt;
Install the RT_SiteConfig.pm file from the krbdev-services repository in /etc/request-tracker4.&lt;br /&gt;
&lt;br /&gt;
In root's crontab file (&amp;quot;crontab -e&amp;quot; as root), add the following to perform daily maintenance:&lt;br /&gt;
&lt;br /&gt;
  MAILTO=krbcore-hw@mit.edu&lt;br /&gt;
  0 3 * * * /usr/sbin/rt-clean-sessions&lt;br /&gt;
  0 4 * * * /var/rt2/bin/krb5-daily.sh&lt;br /&gt;
&lt;br /&gt;
==PostgreSQL configuration==&lt;br /&gt;
&lt;br /&gt;
Many PostgreSQL files live in directories specific to the PostgreSQL major and minor version, such as /etc/postgresql/8.3 for PostgreSQL 8.3.&lt;br /&gt;
&lt;br /&gt;
The Ubuntu postgresql package will create a &amp;quot;main&amp;quot; cluster with a configuration directory in /etc/postgresql/&amp;lt;version&amp;gt;/main.&lt;br /&gt;
&lt;br /&gt;
In /etc/postgresql/&amp;lt;version&amp;gt;/main/pg_ident.conf, add:&lt;br /&gt;
&lt;br /&gt;
  local		root		root&lt;br /&gt;
  local		root		postgres&lt;br /&gt;
  local		root		rt_user&lt;br /&gt;
  local		rt		rt_user&lt;br /&gt;
  local		rtcvs		rt_user&lt;br /&gt;
  local		postfix		rt_user&lt;br /&gt;
  local		nobody		rt_user&lt;br /&gt;
  local         www-data        rt_user&lt;br /&gt;
&lt;br /&gt;
(The entry for &amp;quot;rt&amp;quot; should no longer be needed, but is currently still present.)&lt;br /&gt;
&lt;br /&gt;
In /etc/postgresql/&amp;lt;version&amp;gt;/main/pg_hba.conf, find the line that reads &amp;quot;local all all peer&amp;quot; and add &amp;quot;map=local&amp;quot; to the end, so it reads &amp;quot;local all all peer map=local&amp;quot;.  Comment out the line that reads &amp;quot;local all postgres peer&amp;quot;, despite the warning not to disable it.  Run &amp;quot;service postgresql restart&amp;quot; to reread the affected files.  Run &amp;quot;psql -Upostgres --list&amp;quot; to verify that the identity map works.&lt;br /&gt;
&lt;br /&gt;
Run &amp;quot;createuser -Upostgres rt_user&amp;quot; to create the rt_user role.&lt;br /&gt;
&lt;br /&gt;
Run &amp;quot;/usr/sbin/rt-setup-database --action create&amp;quot; to create the database, then restore it from a backup with &amp;quot;zcat /path/to/dump.gz | psql -d rt4 -Upostgres&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==Postfix configuration==&lt;br /&gt;
&lt;br /&gt;
By default ops manages Postfix with Puppet.  This must be disabled by ops, and the Debian defaults restored by copying /usr/share/postfix/main.cf.debian to /etc/postfix/main.cf and /usr/share/postfix/master.cf.dist to /etc/postfix/master.cf.&lt;br /&gt;
&lt;br /&gt;
At the end of /etc/postfix/main.cf add:&lt;br /&gt;
&lt;br /&gt;
  myhostname = krbdev.mit.edu&lt;br /&gt;
  mydestination = krbdev.mit.edu, kerborg-prod-app-1.mit.edu, localhost.mit.edu, localhost&lt;br /&gt;
  &lt;br /&gt;
  # Suppress some headers to avoid leaking internal addresses to spammers.&lt;br /&gt;
  prepend_delivered_header =&lt;br /&gt;
  enable_original_recipient = no&lt;br /&gt;
  &lt;br /&gt;
  # RT header milter&lt;br /&gt;
  smtpd_milters = unix:private/milter&lt;br /&gt;
&lt;br /&gt;
Copy /etc/aliases from the old server.  To avoid aiding spammers, its contents are not reproduced here.  In particular, /etc/aliases contains an internal address corresponding to the membership of the krb5-bugs-incoming mailman list; revealing this address could allow spammers to bypass moderation of incoming bug reports.&lt;br /&gt;
&lt;br /&gt;
In root's crontab file (&amp;quot;crontab -e&amp;quot; as root):&lt;br /&gt;
&lt;br /&gt;
  @reboot /var/rt2/bin/rtmilter.pl /var/spool/postfix/private/milter&lt;br /&gt;
&lt;br /&gt;
Run the command by hand (backgrounded) to start the milter process before the next reboot.&lt;br /&gt;
&lt;br /&gt;
Run &amp;quot;newaliases&amp;quot; and &amp;quot;postfix reload&amp;quot; to pick up the changed configuration.&lt;br /&gt;
&lt;br /&gt;
Make sure rt@kerborg-prod-app-1.mit.edu and rt-comment@kerborg-prod-app-1.mit.edu are authorized as non-member senders at https://mailman.mit.edu:444/mailman/admin/krb5-bugs/privacy/sender .&lt;br /&gt;
&lt;br /&gt;
==Apache httpd configuration==&lt;br /&gt;
&lt;br /&gt;
Create /etc/apache2/ssl.crt and /etc/apache2/ssl.key.&lt;br /&gt;
&lt;br /&gt;
Copy /etc/apache2/ssl.key/server.key and /etc/apache2/ssl.crt/server.crt from the old server, or follow the instructions at http://kb.mit.edu/confluence/display/istcontrib/Obtaining+an+SSL+certificate+for+a+web+server to obtain a new one.  server.key and server.crt may be symlinks using whatever scheme seems convenient for renewing certificates every few years.&lt;br /&gt;
&lt;br /&gt;
Install /etc/apache2/ssl.crt/chain.crt from /mit/apache-ssl/certificates/InCommon-chain.crt.txt (requires tokens).  Cutting and pasting is effective for transferring certificates as they are represented as short text files.&lt;br /&gt;
&lt;br /&gt;
Install /etc/apache2/ssl.crt/clientCA.crt from /mit/apache-ssl/certificates/mitCAclient.pem (requires tokens).&lt;br /&gt;
&lt;br /&gt;
Install the rt.conf file from the krbdev-services repository as /etc/apache2/sites-available/rt.conf .&lt;br /&gt;
&lt;br /&gt;
Edit /etc/apache2/mods-available/proxy.conf and set:&lt;br /&gt;
&lt;br /&gt;
  ProxyVia On&lt;br /&gt;
&lt;br /&gt;
  ProxyPass /buildbot/ws ws://krbdev-buildbot.mit.edu:8010/ws&lt;br /&gt;
  ProxyPassReverse /buildbos/ws ws://krbdev-buildbot.mit.edu:8010/ws&lt;br /&gt;
  ProxyPass /buildbot/ http://krbdev-buildbot.mit.edu:8010/&lt;br /&gt;
  ProxyPassReverse /buildbot/ http://krbdev-buildbot.mit.edu:8010/&lt;br /&gt;
  &amp;lt;Proxy http://krbdev-buildbot.mit.edu:8010/*&amp;gt;&lt;br /&gt;
          Allow from all&lt;br /&gt;
  &amp;lt;/Proxy&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Edit /etc/apache2/ports.conf and add &amp;quot;Listen 444&amp;quot; in the ssl_module section after &amp;quot;Listen 443&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Clean out /var/www and install index.html and robots.txt from the krbdev-www directory of the krbdev-services repository.&lt;br /&gt;
&lt;br /&gt;
Run:&lt;br /&gt;
&lt;br /&gt;
  a2enmod ssl&lt;br /&gt;
  a2enmod userdir&lt;br /&gt;
  a2enmod rewrite&lt;br /&gt;
  a2enmod proxy_http&lt;br /&gt;
  a2enmod proxy_wstunnel&lt;br /&gt;
  a2dissite 000-default&lt;br /&gt;
  a2ensite rt&lt;br /&gt;
  service apache2 restart&lt;br /&gt;
&lt;br /&gt;
==Testing==&lt;br /&gt;
&lt;br /&gt;
Get a certificate for the new VM's real hostname and temporarily point /etc/apache2/ssl.crt/server.crt at it.&lt;br /&gt;
&lt;br /&gt;
In /etc/request-tracker4/RT_SiteConfig.pm, temporarily set @ReferrerWhitelist to use the real hostname instead of krbdev.mit.edu.&lt;br /&gt;
&lt;br /&gt;
Temporarily set emergency moderation on the krb5-bugs mailing list (at https://mailman.mit.edu:444/mailman/admin/krb5-bugs/general ) to ensure that mail sent to that list as the result of testing is caught in the moderation queue.&lt;br /&gt;
&lt;br /&gt;
Verify that RT displays at https://realhostname/rt and tickets can be accessed.  Verify that https://realhostname:444/ works and that a new ticket can be created.  Respond to the ticket via email and verify that the response is stored in the ticket.&lt;br /&gt;
&lt;br /&gt;
As root, run /var/rt2/bin/krb5-daily.sh and verify that a dump file appears in /var/psqlbackups.&lt;br /&gt;
&lt;br /&gt;
As rtcvs (&amp;quot;su -s /bin/bash - rtcvs&amp;quot;), run /var/rt2/bin/rt-reserve-ticket and verify that a ticket number is printed.&lt;br /&gt;
&lt;br /&gt;
To test rt-cvsgate, create a test message in /tmp/testmsg like so:&lt;br /&gt;
&lt;br /&gt;
  id: NNNN (use the ticket number printed by rt-reserve-ticket above)&lt;br /&gt;
  ticket: new&lt;br /&gt;
  subject: rt-cvsgate test&lt;br /&gt;
  tags: pullup&lt;br /&gt;
&lt;br /&gt;
  test commit message&lt;br /&gt;
&lt;br /&gt;
As rtcvs, run &amp;quot;/var/rt2/bin/rt-cvsgate ''username'' &amp;lt; /tmp/testmsg&amp;quot;, where ''username'' is an authorized user.&lt;br /&gt;
&lt;br /&gt;
Undo the temporary changes and restore the database from a dump file.&lt;br /&gt;
&lt;br /&gt;
==BIND configuration==&lt;br /&gt;
&lt;br /&gt;
The bind9 configuration files can be found in krbdev-services under bind. They should be installed under /etc/bind. &amp;quot;rndc reload&amp;quot; will restart the runing named with the changed configuration. If it is necessary to edit any of the zone files, be sure to update the serial number in the SOA record to the current date followed by &amp;quot;00&amp;quot; (or &amp;quot;01&amp;quot; etc. for successive edits in the same day).&lt;br /&gt;
&lt;br /&gt;
If the IP address if kerberos.org needs to be changed, the glue record at hover.com must be updated. In the current Hover UI, glue records can be found under &amp;quot;advanced&amp;quot;. The transfer lock on the domain must be temporarily disabled (via the Overview screen) to update glue records.&lt;/div&gt;</summary>
		<author><name>Ghudson</name></author>	</entry>

	<entry>
		<id>https://k5wiki.kerberos.org/wiki?title=RT_server_configuration&amp;diff=6018</id>
		<title>RT server configuration</title>
		<link rel="alternate" type="text/html" href="https://k5wiki.kerberos.org/wiki?title=RT_server_configuration&amp;diff=6018"/>
				<updated>2021-06-01T22:42:39Z</updated>
		
		<summary type="html">&lt;p&gt;Ghudson: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page contains notes on the setup of the MIT krb5 RT server. The current server is krbdev.mit.edu (canonical name kerborg-prod-app-1.mit.edu), which runs Ubuntu 20.04.&lt;br /&gt;
&lt;br /&gt;
==Packages==&lt;br /&gt;
&lt;br /&gt;
In Ubuntu 20.04, the request-tracker4 package contains a suitable version of RT.  This package will ask some questions at installation time:&lt;br /&gt;
&lt;br /&gt;
* RT site name: krbdev.mit.edu&lt;br /&gt;
* handle RT_SiteConfig.pm permissions: yes&lt;br /&gt;
* use dbconfig-common: no&lt;br /&gt;
&lt;br /&gt;
The data in RT is stored in a PostgreSQL database.  The postgresql Ubuntu package will install the recommended version of PostgreSQL for the current Ubuntu version.&lt;br /&gt;
&lt;br /&gt;
The mail interface to RT is handled by Postfix, so the postfix package is required.  The libsendmail-pmilter-perl package is required for the custom milter script.&lt;br /&gt;
&lt;br /&gt;
The web front end to RT is an Apache2 web server, so the apache2 package is required.  RT uses a FastCGI server, so the libapache2-mod-fcgid package is required.&lt;br /&gt;
&lt;br /&gt;
The server host acts as an authoritative name server for the kerberos.org zone, so the bind9 package must be installed.&lt;br /&gt;
&lt;br /&gt;
In sum, the following packages must be installed on the RT server:&lt;br /&gt;
&lt;br /&gt;
  apache2&lt;br /&gt;
  bind9&lt;br /&gt;
  libapache2-mod-fcgid&lt;br /&gt;
  libsendmail-pmilter-perl&lt;br /&gt;
  perl&lt;br /&gt;
  perl-base&lt;br /&gt;
  postfix&lt;br /&gt;
  postgresql&lt;br /&gt;
  request-tracker4&lt;br /&gt;
&lt;br /&gt;
==User accounts==&lt;br /&gt;
&lt;br /&gt;
The postgresql package will create a postgres user account.&lt;br /&gt;
&lt;br /&gt;
The following user accounts and group entries must be created manually:&lt;br /&gt;
&lt;br /&gt;
* group rt&lt;br /&gt;
* user rtcvs: primary group rt, homedir /var/rt2, shell /bin/sh&lt;br /&gt;
* user rt: primary group rt, homedir /var/rt2, shell /bin/false&lt;br /&gt;
&lt;br /&gt;
These accounts could be created with:&lt;br /&gt;
&lt;br /&gt;
  groupadd -r rt&lt;br /&gt;
  useradd -r -g rt -d /var/rt2 rtcvs&lt;br /&gt;
  useradd -r -m -g rt -d /var/rt2 -s /bin/false rt&lt;br /&gt;
&lt;br /&gt;
Some of the above accounts may be created by ops during provisioning.  /var/rt2 and /var/rt2/.ssh must be owned by rtcvs or sshd will reject logins as rtcvs from drugstore.&lt;br /&gt;
&lt;br /&gt;
Create /var/rt2/bin and copy in the following scripts from the krbdev-services repository:&lt;br /&gt;
&lt;br /&gt;
  rt-scripts/rt-reserve-ticket&lt;br /&gt;
  rt-scripts/rtmilter.pl&lt;br /&gt;
  rt-scripts/krb5-daily.sh&lt;br /&gt;
  rt-cvs/rt-cvsgate&lt;br /&gt;
&lt;br /&gt;
The scripts and directory should be mode 755 and owned by user rt and group rt.&lt;br /&gt;
&lt;br /&gt;
/var/rt2 should contain an empty .k5login file, managed by ops.  It should contain a .ssh/authorized_keys file, managed by ops, containing the krbsnap key from /git/krb5.git/hooks/krbsnap_rsa_key.pub on drugstore.mit.edu.&lt;br /&gt;
&lt;br /&gt;
Create /var/psqlbackups (owned by root).&lt;br /&gt;
&lt;br /&gt;
The rt user account is not actually needed for the current RT installation, and the homedir name /var/rt2 is outdated.  The following references need to be taken into account when changing the user and group configuration:&lt;br /&gt;
&lt;br /&gt;
* Both the rt and rtcvs accounts have the homedir /var/rt2.&lt;br /&gt;
* krb5-daily.sh references the krbsnap.keytab file and dumps directory in /var/rt2.&lt;br /&gt;
* A root cron job runs krb5-daily.sh from /var/rt2.&lt;br /&gt;
* A root cron job runs rtmilter on boot from /var/rt2.&lt;br /&gt;
* The empty /var/rt2/.k5login file is managed by ops.&lt;br /&gt;
* The /var/rt2/.ssh/authorized_keys file is managed by ops.&lt;br /&gt;
* On drugstore.mit.edu, the krb5 git repository rt-ssh-cmd config value references the rtcvs user and /var/rt2/bin/rt-cvsgate.&lt;br /&gt;
* On drugstore.mit.edu, the krb5 git repository hooks/krb5-rt-id script references the rtcvs user and /var/rt2/bin/rt-reserve-ticket.  This script comes from the krbdev-services repository's githooks/krb5-rt-id.&lt;br /&gt;
* Some of the same references are present in the krbdev-services repository, but they aren't used.&lt;br /&gt;
&lt;br /&gt;
==RT setup==&lt;br /&gt;
&lt;br /&gt;
Install the RT_SiteConfig.pm file from the krbdev-services repository in /etc/request-tracker4.&lt;br /&gt;
&lt;br /&gt;
In root's crontab file (&amp;quot;crontab -e&amp;quot; as root), add the following to perform daily maintenance:&lt;br /&gt;
&lt;br /&gt;
  MAILTO=krbcore-hw@mit.edu&lt;br /&gt;
  0 3 * * * /usr/sbin/rt-clean-sessions&lt;br /&gt;
  0 4 * * * /var/rt2/bin/krb5-daily.sh&lt;br /&gt;
&lt;br /&gt;
==PostgreSQL configuration==&lt;br /&gt;
&lt;br /&gt;
Many PostgreSQL files live in directories specific to the PostgreSQL major and minor version, such as /etc/postgresql/8.3 for PostgreSQL 8.3.&lt;br /&gt;
&lt;br /&gt;
The Ubuntu postgresql package will create a &amp;quot;main&amp;quot; cluster with a configuration directory in /etc/postgresql/&amp;lt;version&amp;gt;/main.&lt;br /&gt;
&lt;br /&gt;
In /etc/postgresql/&amp;lt;version&amp;gt;/main/pg_ident.conf, add:&lt;br /&gt;
&lt;br /&gt;
  local		root		root&lt;br /&gt;
  local		root		postgres&lt;br /&gt;
  local		root		rt_user&lt;br /&gt;
  local		rt		rt_user&lt;br /&gt;
  local		rtcvs		rt_user&lt;br /&gt;
  local		postfix		rt_user&lt;br /&gt;
  local		nobody		rt_user&lt;br /&gt;
  local         www-data        rt_user&lt;br /&gt;
&lt;br /&gt;
(The entry for &amp;quot;rt&amp;quot; should no longer be needed, but is currently still present.)&lt;br /&gt;
&lt;br /&gt;
In /etc/postgresql/&amp;lt;version&amp;gt;/main/pg_hba.conf, find the line that reads &amp;quot;local all all peer&amp;quot; and add &amp;quot;map=local&amp;quot; to the end, so it reads &amp;quot;local all all peer map=local&amp;quot;.  Comment out the line that reads &amp;quot;local all postgres peer&amp;quot;, despite the warning not to disable it.  Run &amp;quot;service postgresql restart&amp;quot; to reread the affected files.  Run &amp;quot;psql -Upostgres --list&amp;quot; to verify that the identity map works.&lt;br /&gt;
&lt;br /&gt;
Run &amp;quot;createuser -Upostgres rt_user&amp;quot; to create the rt_user role.&lt;br /&gt;
&lt;br /&gt;
Run &amp;quot;/usr/sbin/rt-setup-database --action create&amp;quot; to create the database, then restore it from a backup with &amp;quot;zcat /path/to/dump.gz | psql -d rt4 -Upostgres&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==Postfix configuration==&lt;br /&gt;
&lt;br /&gt;
By default ops manages Postfix with Puppet.  This must be disabled by ops, and the Debian defaults restored by copying /usr/share/postfix/main.cf.debian to /etc/postfix/main.cf and /usr/share/postfix/master.cf.dist to /etc/postfix/master.cf.&lt;br /&gt;
&lt;br /&gt;
At the end of /etc/postfix/main.cf add:&lt;br /&gt;
&lt;br /&gt;
  myhostname = krbdev.mit.edu&lt;br /&gt;
  mydestination = krbdev.mit.edu, kerborg-prod-app-1.mit.edu, localhost.mit.edu, localhost&lt;br /&gt;
  &lt;br /&gt;
  # Suppress some headers to avoid leaking internal addresses to spammers.&lt;br /&gt;
  prepend_delivered_header =&lt;br /&gt;
  enable_original_recipient = no&lt;br /&gt;
  &lt;br /&gt;
  # RT header milter&lt;br /&gt;
  smtpd_milters = unix:private/milter&lt;br /&gt;
&lt;br /&gt;
Copy /etc/aliases from the old server.  To avoid aiding spammers, its contents are not reproduced here.  In particular, /etc/aliases contains an internal address corresponding to the membership of the krb5-bugs-incoming mailman list; revealing this address could allow spammers to bypass moderation of incoming bug reports.&lt;br /&gt;
&lt;br /&gt;
In root's crontab file (&amp;quot;crontab -e&amp;quot; as root):&lt;br /&gt;
&lt;br /&gt;
  @reboot /var/rt2/bin/rtmilter.pl /var/spool/postfix/private/milter&lt;br /&gt;
&lt;br /&gt;
Run the command by hand (backgrounded) to start the milter process before the next reboot.&lt;br /&gt;
&lt;br /&gt;
Run &amp;quot;newaliases&amp;quot; and &amp;quot;postfix reload&amp;quot; to pick up the changed configuration.&lt;br /&gt;
&lt;br /&gt;
Make sure rt@kerborg-prod-app-1.mit.edu and rt-comment@kerborg-prod-app-1.mit.edu are authorized as non-member senders at https://mailman.mit.edu:444/mailman/admin/krb5-bugs/privacy/sender .&lt;br /&gt;
&lt;br /&gt;
==Apache httpd configuration==&lt;br /&gt;
&lt;br /&gt;
Create /etc/apache2/ssl.crt and /etc/apache2/ssl.key.&lt;br /&gt;
&lt;br /&gt;
Copy /etc/apache2/ssl.key/server.key and /etc/apache2/ssl.crt/server.crt from the old server, or follow the instructions at http://kb.mit.edu/confluence/display/istcontrib/Obtaining+an+SSL+certificate+for+a+web+server to obtain a new one.  server.key and server.crt may be symlinks using whatever scheme seems convenient for renewing certificates every few years.&lt;br /&gt;
&lt;br /&gt;
Install /etc/apache2/ssl.crt/chain.crt from /mit/apache-ssl/certificates/InCommon-chain.crt.txt (requires tokens).  Cutting and pasting is effective for transferring certificates as they are represented as short text files.&lt;br /&gt;
&lt;br /&gt;
Install /etc/apache2/ssl.crt/clientCA.crt from /mit/apache-ssl/certificates/mitCAclient.pem (requires tokens).&lt;br /&gt;
&lt;br /&gt;
Install the rt.conf file from the krbdev-services repository as /etc/apache2/sites-available/rt.conf .&lt;br /&gt;
&lt;br /&gt;
Edit /etc/apache2/mods-available/proxy.conf and set:&lt;br /&gt;
&lt;br /&gt;
  ProxyVia On&lt;br /&gt;
&lt;br /&gt;
  ProxyPass /buildbot/ws ws://krbdev-buildbot.mit.edu:8010/ws&lt;br /&gt;
  ProxyPassReverse /buildbos/ws ws://krbdev-buildbot.mit.edu:8010/ws&lt;br /&gt;
  ProxyPass /buildbot/ http://krbdev-buildbot.mit.edu:8010/&lt;br /&gt;
  ProxyPassReverse /buildbot/ http://krbdev-buildbot.mit.edu:8010/&lt;br /&gt;
  &amp;lt;Proxy http://krbdev-buildbot.mit.edu:8010/*&amp;gt;&lt;br /&gt;
          Allow from all&lt;br /&gt;
  &amp;lt;/Proxy&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Edit /etc/apache2/ports.conf and add &amp;quot;Listen 444&amp;quot; in the ssl_module section after &amp;quot;Listen 443&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Clean out /var/www and install index.html and robots.txt from the krbdev-www directory of the krbdev-services repository.&lt;br /&gt;
&lt;br /&gt;
Run:&lt;br /&gt;
&lt;br /&gt;
  a2enmod ssl&lt;br /&gt;
  a2enmod userdir&lt;br /&gt;
  a2enmod rewrite&lt;br /&gt;
  a2enmod proxy_http&lt;br /&gt;
  a2enmod proxy_wstunnel&lt;br /&gt;
  a2dissite 000-default&lt;br /&gt;
  a2ensite rt&lt;br /&gt;
  service apache2 restart&lt;br /&gt;
&lt;br /&gt;
==Testing==&lt;br /&gt;
&lt;br /&gt;
Get a certificate for the new VM's real hostname and temporarily point /etc/apache2/ssl.crt/server.crt at it.&lt;br /&gt;
&lt;br /&gt;
In /etc/request-tracker4/RT_SiteConfig.pm, temporarily set @ReferrerWhitelist to use the real hostname instead of krbdev.mit.edu.&lt;br /&gt;
&lt;br /&gt;
Temporarily set emergency moderation on the krb5-bugs mailing list (at https://mailman.mit.edu:444/mailman/admin/krb5-bugs/general ) to ensure that mail sent to that list as the result of testing is caught in the moderation queue.&lt;br /&gt;
&lt;br /&gt;
Verify that RT displays at https://realhostname/rt and tickets can be accessed.  Verify that https://realhostname:444/ works and that a new ticket can be created.  Respond to the ticket via email and verify that the response is stored in the ticket.&lt;br /&gt;
&lt;br /&gt;
As root, run /var/rt2/bin/krb5-daily.sh and verify that a dump file appears in /var/psqlbackups.&lt;br /&gt;
&lt;br /&gt;
As rtcvs (&amp;quot;su -s /bin/bash - rtcvs&amp;quot;), run /var/rt2/bin/rt-reserve-ticket and verify that a ticket number is printed.&lt;br /&gt;
&lt;br /&gt;
To test rt-cvsgate, create a test message in /tmp/testmsg like so:&lt;br /&gt;
&lt;br /&gt;
  id: NNNN (use the ticket number printed by rt-reserve-ticket above)&lt;br /&gt;
  ticket: new&lt;br /&gt;
  subject: rt-cvsgate test&lt;br /&gt;
  tags: pullup&lt;br /&gt;
&lt;br /&gt;
  test commit message&lt;br /&gt;
&lt;br /&gt;
As rt-cvsgate, run &amp;quot;/var/rt2/bin/rt-cvsgate ''username'' &amp;lt; /tmp/testmsg&amp;quot;, where ''username'' is an authorized user.&lt;br /&gt;
&lt;br /&gt;
Undo the temporary changes and restore the database from a dump file.&lt;br /&gt;
&lt;br /&gt;
==BIND configuration==&lt;br /&gt;
&lt;br /&gt;
The bind9 configuration files can be found in krbdev-services under bind. They should be installed under /etc/bind. &amp;quot;rndc reload&amp;quot; will restart the runing named with the changed configuration. If it is necessary to edit any of the zone files, be sure to update the serial number in the SOA record to the current date followed by &amp;quot;00&amp;quot; (or &amp;quot;01&amp;quot; etc. for successive edits in the same day).&lt;br /&gt;
&lt;br /&gt;
If the IP address if kerberos.org needs to be changed, the glue record at hover.com must be updated. In the current Hover UI, glue records can be found under &amp;quot;advanced&amp;quot;. The transfer lock on the domain must be temporarily disabled (via the Overview screen) to update glue records.&lt;/div&gt;</summary>
		<author><name>Ghudson</name></author>	</entry>

	<entry>
		<id>https://k5wiki.kerberos.org/wiki?title=Developer_chat&amp;diff=6017</id>
		<title>Developer chat</title>
		<link rel="alternate" type="text/html" href="https://k5wiki.kerberos.org/wiki?title=Developer_chat&amp;diff=6017"/>
				<updated>2021-06-01T22:36:22Z</updated>
		
		<summary type="html">&lt;p&gt;Ghudson: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;MIT Kerberos developers use several venues for instant message chat.&lt;br /&gt;
&lt;br /&gt;
== IRC channels ==&lt;br /&gt;
&lt;br /&gt;
The main IRC channel for MIT Kerberos development is &amp;lt;code&amp;gt;#krbdev&amp;lt;/code&amp;gt; on Libera Chat.  There is a separate channel, &amp;lt;code&amp;gt;#kerberos&amp;lt;/code&amp;gt;, for general Kerberos discussion and support.&lt;br /&gt;
&lt;br /&gt;
For more information about Libera Chat, see https://libera.chat/.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;#krbdev&amp;lt;/code&amp;gt; channel is logged at http://colabti.org/irclogger/irclogger_logs/krbdev using the colabti.org service, which generously offers IRC logging to Free / Open Source projects.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;#krbdev&amp;lt;/code&amp;gt; channel was previously logged by lopbot, courtesy of Brandon Allbery. These logs are no longer readily available online. Despite the possible existence of logging, please summarize important conversations to more permanent places, such as an appropriate mailing list or wiki page.&lt;/div&gt;</summary>
		<author><name>Ghudson</name></author>	</entry>

	</feed>