Determine Authenticating Domain Controller

Back when Server 2003 was the new hot thing, password policy could only be set at the domain level. Since then, Password Security Objects were introduced in Active Directory, beginning with Server 2008. PSO are like GPO’s and can be scoped to a specific OU, user, or group. In order to use PSO, ensure domain policy as defined in a GPO has been cleared out first.
To learn more about PSO, read the following: Fine Grained Password Policy

I was troubleshooting an issue where a user was unable to update their password, despite meeting password complexity requirements. Evidently, the minimum password age was set to 30, so they were prevented from creating a new password, in that 30 day window, until I changed the min. password age to 0.

Another few commands I found useful during this project were:

Determine computer / server DC using nltest

nltest /dsgetdc:<domain>

List all DC’s

nltest /dclist:<domain>

Determine server used for user authentication:

echo %logonserver%

Build a weather station using esp8266, ssd1306, dht22

In this post I present an overview building a weather station I could place in my garden, hoping to monitor temperature and humidity. I’ll use a esp8266 NodeMCU WiFi module to stream this data to Losant, an IOT platform. We’ll also display these readings on a ssd1306 0.96″ OLED screen. The temperature and humidity are observed using a DHT22 sensor module.  Eventually I’ll add moisture probes that will be used to trigger relays used to active a sprinkler during the hot, dry months of July and August in Wisconsin. Other goals include adding sensors to monitor rainfall, wind speed, and wind direction.

My code went through a few iterations to start. I wanted to take readings from the DHT22 and put them on the console monitor. I also printed some simple banner to the OLED display as well. At one point I found an i2c scanner to ensure my laptop could see the esp8266. In the end, I combined code with the examples from Losant to stream sensors readings to the cloud over WiFi and to a 128×64 OLED.

i2c Scanner

// --------------------------------------
// i2c_scanner
// Version 1
// This program (or code that looks like it)
// can be found in many places.
// For example on the forum.
// The original author is not know.
// Version 2, Juni 2012, Using Arduino 1.0.1
// Adapted to be as simple as possible by user Krodal
// Version 3, Feb 26 2013
// V3 by louarnold
// Version 4, March 3, 2013, Using Arduino 1.0.3
// by user Krodal.
// Changes by louarnold removed.
// Scanning addresses changed from 0...127 to 1...119,
// according to the i2c scanner by Nick Gammon
// Version 5, March 28, 2013
// As version 4, but address scans now to 127.
// A sensor seems to use address 120.
// Version 6, November 27, 2015.
// Added waiting for the Leonardo serial communication.
// This sketch tests the standard 7-bit addresses
// Devices with higher bit address might not be seen properly.
#include <Wire.h>
void setup()
 while (!Serial); // Leonardo: wait for serial monitor
 Serial.println("\nI2C Scanner");
void loop()
 byte error, address;
 int nDevices;

 nDevices = 0;
 for(address = 1; address < 127; address++ )
 // The i2c_scanner uses the return value of
 // the Write.endTransmisstion to see if
 // a device did acknowledge to the address.
 error = Wire.endTransmission();
 if (error == 0)
 Serial.print("I2C device found at address 0x");
 if (address<16)
 Serial.println(" !");
 else if (error==4)
 Serial.print("Unknown error at address 0x");
 if (address<16)
 if (nDevices == 0)
 Serial.println("No I2C devices found\n");
 delay(5000); // wait 5 seconds for next scan

128×64 OLED Test

The small display relies on the i2c communication protocol, as does the DHT22, making connections to the esp8266 very straightforward. The display has 4 pins: 3-5v logic, ground, serial clock (SCL) and serial data (SDA).

It’s essential to connect SCL,SDA pins of oled display to pins on esp8266 marked D1 and D2.

The key is to load the Adafruit_GFX and Adafruit_SSD1306 libraries.

#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

Adafruit_SSD1306 display(OLED_RESET);

#if (SSD1306_LCDHEIGHT != 64)
#error("Height incorrect, please fix Adafruit_SSD1306.h!");

void setup() {
 display.begin(SSD1306_SWITCHCAPVCC, 0x3C);

// Clear the buffer.

 display.println("Hello from:");


void loop() {
 // put your main code here, to run repeatedly:


Read DHT22 and display on OLED – Borrowed from Losant

 * Example for reading temperature and humidity
 * using the DHT22 and ESP8266
 * Copyright (c) 2016 Losant IoT. All rights reserved.

#include "DHT.h";
#define DHTPIN 2 // what digital pin the DHT22 is conected to
#define DHTTYPE DHT22 // there are multiple kinds of DHT sensors

//#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
Adafruit_SSD1306 display(OLED_RESET);

void setup() {

 // Wait for serial to initialize.
 while(!Serial) { }

Serial.println("Device Started");
 Serial.println("Running DHT!");


int timeSinceLastRead = 0;
void loop() {

// Report every 2 seconds.
 if(timeSinceLastRead > 2000) {
 // Reading temperature or humidity takes about 250 milliseconds!
 // Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
 float h = dht.readHumidity();
 // Read temperature as Celsius (the default)
 float t = dht.readTemperature();
 // Read temperature as Fahrenheit (isFahrenheit = true)
 float f = dht.readTemperature(true);

// Check if any reads failed and exit early (to try again).
 if (isnan(h) || isnan(t) || isnan(f)) {
 Serial.println("Failed to read from DHT sensor!");
 timeSinceLastRead = 0;

// Compute heat index in Fahrenheit (the default)
 float hif = dht.computeHeatIndex(f, h);
 // Compute heat index in Celsius (isFahreheit = false)
 float hic = dht.computeHeatIndex(t, h, false);

Serial.print("Humidity: ");
 Serial.print(" %\t");
 Serial.print("Temperature: ");
 Serial.print(" *C ");
 Serial.print(" *F\t");
 Serial.print("Heat index: ");
 Serial.print(" *C ");
 Serial.println(" *F");

// Clear the buffer.
 display.begin(SSD1306_SWITCHCAPVCC, 0x3c); // initialize with the I2C addr 0x3D (for the 128x64)
 // Clear the buffer.

 //char temperature[5] = "";
 //dtostrf(hif, 3,1,temperature);
 String buf;
 buf += F("Temperature: ");
 buf += String(hif,2);
 buf += " F";
 buf += F("Humidity: ");
 buf += String(h,2);
 buf += "%";
 //char humidity[5] = "";
 //dtostrf(h, 3,1,humidity);

/* //Send Temp & Humidity to OLED
 display.println("Temperature: *F");
 display.println("Humidity: %");
 display.println("Temperature: F");
 display.println("Humidity: %");

timeSinceLastRead = 0;
 timeSinceLastRead += 100;

Losant Example

The Whole Kaboodle



Reset Computer Machine Password

Occasionally I’ll receive a report that domain users cannot login to a specific laptop, citing an error message “The trust relationship between this workstation and the primary domain failed.” It’s worth noting that although domain accounts cannot be used to sign in, local computer accounts may still be used.

Microsoft has issued two solutions to this problem. One solution involves logging into the PC using a local computer account and taking the PC off the domain, reboot, sign in again with local account, and once more join the laptop to the domain. This works, but it’s slow.

A better solution that takes less time requires us to use a powershell cmdlet. Again, login to the PC with a local account and issue the following in Powershell running with Administrative rights.

$creds = Get-Credential
Reset-ComputerMachinePassword -Credential $creds -Server

The first command will display a prompt that will collect username and password that will be used to execute the next cmdlet. Be aware you must provide an account with Domain Admin privileges. After execution, log out. You may now log in again using domain accounts.

Youtube Restricted Mode

Youtube is a great resource for learning and entertainment. However, it can also be a great distraction too. In addition to that, there is a considerable amount of content that many would find questionable at best. In order to filter the most offensive content we can employ Youtube restricted or moderate restricted mode.

Although there are many ways to accomplish this, including setting domain wide user policies in Google admin console, this will only target folks who are using their Google profile that was provided by their employer. To ensure we apply this policy to everyone, we can use DNS redirection.

It’s worth noting some articles suggested creating a DNAME record in each zone that points to either or In my experience this failed. I had success creating an A record instead for each zone.

This article makes the assumption you administer a Windows based DNS server. To begin, create 5 new forward lookup zones:

Within each zone, create a new A record. Leave the Name field blank and enter in the IP Address field. Use for restricted mode, or for moderate restricted mode.

After having done this you should be able to open a browser and verify the changes by heading to


Global Protect LDAP over SSL

I recently had need to reconfigure LDAP settings on a Palo Alto firewall. I had retired two production domain controllers and stood up two new boxes in their place. Remote access VPN users are authenticated by the firewall via LDAP on port 389, or LDAP over SSL (LDAPS) on port 636.

The quickest solution was to provide the firewall with the FQDN, IP Address, and port numbers needed to communicate with the new domain controllers using the LDAP protocol. Ensure ‘Require SSL/TLS secured connection’ is not selected

I make this note as I had assumed the new domain controllers were talking LDAPS by default but I was wrong. A quick look over the authentication log, authd.log, using the command  > tail follow yes mp-log authd.log, revealed this:

2018-07-11 09:05:04.826 -0500 Error: pan_authd_ldap_bind(pan_authd_shared_ldap.c:615): Failed to bind ldap (Can't contact LDAP server)
2018-07-11 09:05:04.826 -0500 Error: pan_auth_create_a_ldap_session(pan_auth_svr_cctxt.c:1971): Failed to bind, get out
2018-07-11 09:05:04.827 -0500 debug: pan_auth_response_process(pan_auth_state_engine.c:4073): auth status: auth server not available

A more secure implementation would take advantage of LDAPS. In a nutshell, you will need to generate your own self-signed certificate, or better, install a certificate provided to you by a CA. Also, LDP.exe is a helpful utility that can verify a successful connection or binding to your directory. It can be obtained by downloading the Microsoft Remote Server Administration Tools (RSAT)

In this post I’ll review configuring my new domain controllers with self-signed certificates in lieu of obtaining signed certificates from a CA. To start, open Server Manager on a new domain controller and install the Active Directory Certificate Services role. As you proceed through the wizard, be sure to configure AD-CS as an Enterprise, Root CA. 

Open the Certificate Templates Console: Launch mmc.exe and add the Certificate Templates snap in and click OK. In the left pane of the snap in right click the domain controller and click View Object Identifiers. In the dialog window, scroll down to the Server Authentication Policy and ensure the Object Identifier is displayed as

Add the Certificates snap in to MMC and instruct the Certificates snap in to manage certificates for the Computer account. Expand the Personal folder in Certificates snap in and right click on the Certificates sub folder, select All Tasks -> Request New Certificate. Select Active Directory Enrollment Policy and click Next. Select Domain Controller and click Enroll. Once finished you’ll see a certificate issued to each domain controller in the domain. You can view these new certificates now in the Local Computer Certificate Store, specifically within the Personal->Certificates sub-node.

At this point, your domain controller should be configured to respond to connection attempts using LDAPS. You can verify this using the LDP.exe utility from Microsoft.





How to Troubleshoot LDAP Authentication

Troubleshooting GlobalProtect

Configuring Secure LDAP Connection on Server 2016



Import Palo Alto Firewall Appliance into GNS3

After obtaining a virtual machine in the form of an OVA file, we need to expand the archive and convert the vmdk to a qcow2 format as specified during the GNS3 Import Appliance dialogue.  The full instructions to convert an OVA to a qcow2 format can be found at

tar xvf pa-vm-esxi-8.0.0.ova

A prerequisite package must be installed to provide us with the means to make the conversion.

apt -y install qemu

With the qemu package installed, we can begin the conversion.

qemu-img convert -f vmdk $FILE-disk1.vmdk -O qcow2 $FILE.qcow2

Virtualbox Shared Folder Missing

Here is a short write up of my experience configuring Shared Folders under Oracle Virtualbox 5.2.2 for a Kali 2017.3  appliance. After importing the appliance, I am warned USB 2.0 can only be supported after installing the Oracle Virtualbox Extension Pack, obtained here. You can double click on the installer and Virtualbox will pick up and carry the installation through completion. After that, I reboot.

Next step is to install the  virtualbox-guest-x11 package instead of using the supplied package available through the cdrom0 device in vm settings. I try the advice listed here. After a reboot, I check /media and there is still no monted folder.

Turns out I need to manually mount the drive in my guest operating system.

mount -t vboxsf -o uid=1000,gid=1000 C_DRIVE ~/Documents/cdrive/

Additional resources regarding shared folders can be referenced on the Ubuntu wiki.

I was curious what the options, “-o uid=1000, gid=1000″ meant. Turns out we’re setting the owners of this folder to the user with an id of 1000 and the group with an id of 1000. If you’d like to discover the uid and gid of a user, run the following two commands.

id -u <username>

id -g <groupname>

You can learn more about userid and groupid by having a look at this help page at Indiana University.




Apple Printer Resource Path

When creating a payload in Apple Profile Manager, you need to not only specify the IP address, but also a resource path.

The best way to do so to issue ippfind from a box running MacOS.

Practical Packet Analysis Notes 2

This 2nd post continues my notes from reading Practical Packet Analysis.

Unreachable port / Unreachable host

A loss of network connectivity can often be seen in Wireshark. For example, a Windows host will attempt 5 re-transmissions. While Wireshark does label these TCP Retransmission, you can also identify this process as each packet has the same Sequence value.

Often the the reply to an echo will source from a switch or router, and often you’ll observe an ARP request for the destination host to reply with a MAC address. This reply can be ICMP type 0 or 3. Code 1 in the ICMP packet = host unreachable. Code2 = port unreachable.


When layer 4 hands segments to layer 3 that are greater than 1500 bytes, the limit that can be carried in a frame across layer 2, the IP packets will be fragmented to fit.

Looking at the IP layer details of such a packet you can see Flags set to 0x01, meaning more fragments follow. The offset of the first packet in this data stream will be 0. The following fragment will show an offset ~1480. Fragmented packets will follow until the last arrives with a flag of 0x00 and that means no more fragments will follow.