simplesamlphp / simplesamlphp/simplesamlphp-module-negotiate

Checking Windows machines domain membership

Open
#9 7 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
PHP
Stars
4
Forks
5
PR merge metrics
No merged PRs in 30d

Description

I noticed in the documentation mention of the issue with Windows machines popping up NTLM authentication boxes, which rather negates the point of the Negotiate module. We hit this some years ago with earlier version of simpleSAMLphp, and we couldn't just limit it by subnet as our users use a mix of organisationally owned domain bound machines and their own devices when on site.

I wrote a little work round that uses an extra, optional string in the negotiate module configuration in authsources.php called checkDomain. This is the AD domain name that the machine should be in. I then added an extra routine to the src/Auth/Source/Negotiate.php code to check this, with a call just after the subnet mask checks. It uses /usr/bin/nmblookup to search for the Windows machine, and ignores browsers that don't include "Windows NT" in their user agent string (so Linux boxes, Macs, etc).

In case it is of use, here's a diff of the changes against a recent version of the negotiate module:

$ diff Negotiate.php.dist Negotiate.php
58d57
< 
82a82
> 	$this->check_domain = $cfg->getOptionalString('checkDomain', NULL);
131a132,139
>         // Check if client is in allowed AD domain
>         $domainOK = $this->checkDomain();
>         if (!$domainOK) {
>             Logger::debug('Negotiate - Not a matching domain. falling back');
>             $this->fallBack($state);
> 	    return;
>         }
> 
226a235,267
>        /**
>          * checkDomain() looks up the domain that the client is bound into
>          *               and limits clients to the specified domain.
>          *
>          * Will return TRUE if no domain restriction option is configured.
>          *
>          * @return boolean
>          */
>         public function checkDomain(): bool {
>                 // No domain means all clients are accepted.
>                 if ($this->check_domain === NULL)
>                         return true;
> 
>                 // Only do this check for Windoze machines.
>                 $ua = $_SERVER['HTTP_USER_AGENT'];
>                 if (!preg_match("/Windows NT/", $ua)) {
>                    return true;           
>                 }
> 
>                 $ip = $_SERVER['REMOTE_ADDR'];
>                 $cmd = "/usr/bin/timeout 1 /usr/bin/nmblookup -A $ip 2>&1";
>                 $shellOutput = shell_exec($cmd);
>                 error_log($shellOutput,0);
>                 $lines = explode(PHP_EOL, $shellOutput);
>                 $myDomain = $this->check_domain;
>                 foreach ($lines as $line) {
>                   if(preg_match("/$myDomain\s+\<00\>\s\-\s\<GROUP\>.+ACTIVE/",
>                                 $line)) {
>                     return true;
>                   }
>                 }
>                 return false;
>         }

We've been using this in production on SSP 1.x IdP servers for many years now, and I've just ported it ready for use to move to SSP 2.x.

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Read src/Auth/Source/Negotiate.php and the authsources.php configuration, starting at the existing subnet checks and the supplied diff. Verify how the optional checkDomain setting should interact with Windows NT user agents, nmblookup, and fallback behavior; the work is done when the documented configuration and domain check are integrated with appropriate verification.

Written by the indexing model from the issue text.

Assessment

Tech stack
php
Domain
authentication
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Clearly specified
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.