Wednesday, June 15, 2016

My thoughts on the Orlando Shooting, Omar Mateen, and the fate of this country

[Reposted from Facebook]

Just so y'all know, i'm not keeping it in anymore. You know where the unfriend button is if you dont like what im saying. You can disagree with me and we'll talk civilly about it but bullshit memes and feel good fiction aint cutting it anymore. Keep your thoughts and prayers to your self. Keep your flags crosses and bibles in your pocket. Keep your whitewashing, profiling, warmongering, hide in the basement fear that the sky is falling to your damn selves. America put a man on the moon and we can fix this ourselves with policy and compassion not war and death.

A good friend reminded me today that not only was this a massacre of human life that could have been prevented, it's ferocity is increased with every hateful word and every hateful action that others perform in the name of GOD. LGBTQ people are human beings, they just want to exist in peace and they are under CONSTANT attack from all directions just because they exist. This wasnt just about guns, this was about hate. It was about the hate that so poisons this country right now that people claim that these acts of mass murder are somehow justified by GOD and their religion. When we talk about just the guns we forget about the HUMANS that died who were just trying to exist and be free. Hijacking the message and the mourning to say "bad guns bad" is not the intent, but in this country all this hate and all these guns add up to a lot more of this type of thing. More guns and more hate doesnt fix it. Hate doesn't defeat hate.

People and the media are so quick to blame "the terrorists, over there" for this. Its not them. Its us. This is what our politicians meant when they said this is our problem. This is our hate baby. We birthed it, we nursed it with innuendo and sly jokes, and we brought it out into the world the full disgusting piece of filth that it is, on every mainstream tv channel, every day with "hate those people" .. hate the mexicans, hate the blacks, hate the gays, hate the people that disagree with us, hate the people that arent phanatical enough. Enough is enough, its time to stop, its time to start unwinding the hate coil that is wound so damn tightly now that our country is on the verge of destruction.  All you need to do is open your eyes and look around at who is hating who. Who is attacking who. I don't see isis flags on the corner, I see talking heads, people with big mouths and no soul, looking to gain from the hate. How could this have been prevented? Stop hating people that are different from you. Stop hating people who you percieve as lazy, when meanwhile the deck has been stacked against them for generations. Stop hating the person you do not know just because someone said you should hate them.

Tuesday, October 6, 2015

Changing the service account credentials in SQL Server

Like most people, when I first start out setting up something new I take the defaults, and that usually is good enough.  Then down the road, while learning more about how the product works, I discover that the defaults don't cut it in some cases.  Microsoft SQL Server is one example.  Out of the box it defaults to using a local account for its services, "nt service\mssql$instancename".  That works fine until you start doing stuff like replication, mirroring, or interacting with active directory with impersonation.  These functions need a domain account, either to share credentials, or to have access to read active directory.

Seems simple enough -- go into the SQL Server Configuration Manager, change the old local account name associated with the service ("nt service\mssql$prod") to a domain account ("ad1\mssql$prod"), and set the account password.  I had previously set up another instance of sql server with this new account, so I know that it was granted all the appropriate permissions at the domain level, and even at the machine level.   Should be a no-brainer to switch over to it right?  Nope.  When you do that, and restart SQL server, it seems fine (locally) until you try and connect from another machine.  Then you get this dreaded error.


The target principal name is incorrect. Cannot generate SSPI context. (Microsoft SQL Server)

Nothing shows up in the sqlserver log files (server side).  Client side, maybe, but I couldn't easily find it.  After googling for what felt like an eternity I stumbled across a forum post that said to do this from an elevated command prompt:
setspn -a mssqlsvc/12data4.ad1 mssql$prod
This fixed it immediately for the entire domain.  It has something to do with kerberos black magic.  So there you have it, I hope this post saves you some time and effort.  It seems to me that changing the account via SQL Server Configuration Manager ought to do this for you, but alas it does not?

Thursday, August 6, 2015

Extending VB.NET objects that are marked as NotInheritable

One of the neat things in VB.Net is something called an "Extension" which allows you to extend the ability of other classes (even if its not possible to subclass the object with inheritance).  For example, in vb6 a lot of times we use Left$() and Right$() to work with strings, and there is a vb.net version of these (right() and left()) but it doesn't exist as a method as part of the string itself.  For example,

dim MyString as string = "hello"
debug.print left(myString,1) <-- prints 'h'

but you can use the ToUpper method right off the string itself...

debug.print myString.ToUpper <-- the same as ucase(myString)

The code below adds 'left' and 'right' extensions to the string class so you can do this ..

Imports Example.Code.StringExtensions
debug.print mystring.toupper.left(1) 

I also added 'qptrim' as an extension of the trim method that strips out nulls as well.  

debug.print mystring.qptrim

Below is how you implement extensions in VB.NET.  You can use this to add extensions to type or class in your project. 

Imports System.Runtime.CompilerServices   '' Adds <Extension()> 

Namespace Global.Example.Code

  Module StringExtensions
    <Extension()>  '' Add QPTrim() method to a standard String
    Public Function QPTrim(ByVal myStr As String) As String
      Return Replace(myStr, Chr(0), "").Trim
    End Function

    <Extension()>  '' Add Right() method to a standard String
    Public Function Right(ByVal myStr As String, ByVal nChars As Integer) As String
      Return myStr.Substring(myStr.Length - nChars, nChars)
    End Function

    <Extension()>  '' Add Left() method to a standard String
    Public Function Left(ByVal myStr As String, ByVal nChars As Integer) As String
      Return myStr.Substring(0, nChars)
    End Function

    <Extension()>  '' Add NoSlash() method to a standard String
    Public Function NoSlash(ByVal myStr As String) As String
      While myStr.Right(1) = "\"
        myStr = myStr.Left(myStr.Length - 1)
      End While
      Return myStr
    End Function
  End Module
End Namespace






Arguably, .NET Purists see this as syntactic sugar.  True, the extension is merely an alternative to calling a function and passing the current string into the function.  However I think the extensions really contribute to readability, especially when you combine multiple methods together.  

Tuesday, November 25, 2014

Installing OTRS 4.0 on Ubuntu Linux 14.04 with a MSSQL Backend

A couple of quick notes... this is not my usual style, this is fairly cutting edge with OTRS 4.0 released yesterday. I've been tinkering around with the beta for a while, and I wanted to do the install from scratch AND use Microsoft SQL Server for the data store. If you have been trying to do this yourself, like me you discovered it's not officially supported. The OTRS group wants you to install on Windows (blech).

I'm here to tell you, this is possible, with some extra fiddling around. The biggest fiddle is getting an ODBC driver installed on Linux that will talk to Microsoft SQL Server, and is free.

I used Microsoft SQL Server 2008 as my backend server, but I imagine any SQL Server version will do. Without further adieu, here's my notes. This is basically a rough draft, if you find this interesting and need more info, leave a comment.

# Download source
cd /opt
wget http://ftp.otrs.org/pub/otrs/otrs-4.0.1.tar.gz
# Install Pre-requisites
apt-get install apache2
apt-get install libapache2-mod-perl2 libtimedate-perl libnet-dns-perl libnet-ldap-perl libio-socket-ssl-perl libpdf-api2-perl libsoap-lite-perl libgd-text-perl libtext-csv-xs-perl libjson-xs-perl libgd-graph-perl libapache-dbi-perl
apt-get install libdbd-sybase-perl
# Enable Perl module for apache
a2enmod perl
# Download official SQL Server driver for linux
# Credit - http://onefinepub.com/2013/03/ms-sql-odbc-ubuntu/
wget http://download.microsoft.com/download/B/C/D/BCDD264C-7517-4B7D-8159-C99FC5535680/RedHat6/msodbcsql-11.0.2270.0.tar.gz
tar -zxvf msodbcsql-11.0.2270.0.tar.gz
# Install unixODBC
# Credit - http://onefinepub.com/2014/03/installing-unixodbc-2-3-2-higher-ubuntu-12-04-lts/
apt-get remove libodbc1 unixodbc unixodbc-dev
apt-get install build-essential
apt-get install openssl libkrb5-3 libc6 e2fsprogs
wget ftp://ftp.unixodbc.org/pub/unixODBC/unixODBC-2.3.2.tar.gz
tar -zxvf unixODBC-2.3.2.tar.gz
cd unixODBC-2.3.2
./configure --enable-gui=no --enable-drivers=no --enable-stats=no --enable-iconv --with-iconv-char-enc=UTF8 --with-iconv-ucode-enc=UTF16LE --libdir=/usr/lib/x86_64-linux-gnu --prefix=/usr --sysconfdir=/etc
make install
cd ..
cd msodbcsql-11.0.2270.0
mv build_dm.sh build_dm.ms
mv install.sh install.ms
# Get build scripts
# Credit - http://onefinepub.com/2014/03/installing-unixodbc-2-3-2-higher-ubuntu-12-04-lts/
wget https://raw.github.com/Andrewpk/Microsoft--SQL-Server--ODBC-Driver-1.0-for-Linux-Fixed-Install-Scripts/master/build_dm.sh
wget https://raw.github.com/Andrewpk/Microsoft--SQL-Server--ODBC-Driver-1.0-for-Linux-Fixed-Install-Scripts/master/install.sh
chmod u+x install.sh; sudo bash install.sh install --accept-license --force
# Create needed symlinks for ODBC Driver to work
ln -s /lib/x86_64-linux-gnu/libcrypto.so.1.0.0 /usr/lib/x86_64-linux-gnu/libcrypto.so.10
ln -s /lib/x86_64-linux-gnu/libssl.so.1.0.0 /usr/lib/x86_64-linux-gnu/libssl.so.10
ln -s /usr/lib/x86_64-linux-gnu/libodbcinst.so.2.0.0 /usr/lib/x86_64-linux-gnu/libodbcinst.so.1
ln -s /usr/lib/x86_64-linux-gnu/libodbc.so.2.0.0 /usr/lib/x86_64-linux-gnu/libodbc.so.1
# Test SQL Driver directly
sqlcmd -S{servername} -U{username} -P{password}
# Create ODBC Driver Entry
vim /etc/odbcinst.ini
[SQL Server]
Description=Microsoft ODBC Driver 11 for SQL Server
Driver=/opt/microsoft/msodbcsql/lib64/libmsodbcsql-11.0.so.2270.0
Threading=1
UsageCount=1
# Create ODBC Test DSN
vim /etc/odbc.ini
[testdsn]
Driver=SQL Server
Description=My Test SQL Server
Trace=Yes
Server={servername}
Port=1433
# Test ODBC Driver connectivity to SQL Server
isql testdsn {username} {pass}

# Create OTRS user (local)
useradd -r -d /opt/otrs/ -c 'OTRS user' otrs
usermod -G nogroup otrs
# Unpack OTRS Source
cd /opt
tar -zxvf otrs-4.0.1.tar.gz
mv otrs-4.0.1 otrs
cd /opt/otrs/Kernel/
cp Config.pm.dist Config.pm
cd Config
cp GenericAgent.pm.dist GenericAgent.pm
# Edit Installer script, this is where the magic happens
vim /opt/otrs/Kernel/Modules/Installer.pm
# Comment out the code section below that disables mssql install on Linux !!!
>> # OTRS can only run on SQL Server if OTRS is on Windows as well
>> if ( $^O ne 'MSWin32' ) {
>> delete $Databases{mssql};
>> }
# Fix the ODBC Driver String so it's compatible with Linux !!!
>> :%s/DBI:ODBC:driver/DBI:ODBC:DRIVER/g
>> :wq
# Set permissions per the OTRS instructions
cd /opt/otrs/bin
./otrs.SetPermissions.pl /opt/otrs --otrs-user=otrs --web-group=www-data
./otrs.CheckModules.pl
service apache2 restart
# Launch the OTRS installer web page
>> http://(servername}/otrs/installer.pl
# Follow the instructions
# select mssql, enter your server name, 'sa' or equivalent account, etc
# Click Test-connection
# It works! amirite?  If this works for you or you find any errors, please comment and let me know what you think!

Tuesday, September 16, 2014

that new old thing: a date2num implementation in vb.net

Hell must be freezing over because I'm doing a lot more VB.NET development these days. Visual Studio 2013 and the .NET 4.5 framework are, in my opinion, the first usable versions of these products. As part of a project to port some of our legacy code from VB6 to VB.NET I've been converting all of the common functions and shared utility libraries we've built up over the years. Some libraries date back to the migration from QuickBasic/PDS 7 on DOS to Visual Basic on Windows.

Back in those days we used very simple yet powerful functions to do things like date math accurately. For example, in the old days, programmers had to account for leap year manually, if they didn't have a good toolset on hand. One of those toolsets was called QuickPak, a library of handy functions written in Assembler that could be linked to your BASIC program to do these things accurately and easily.

The function that sold systems -- our systems -- as being the most accurate product on the market at the time, was a function called Date2num. In short, its the number of days elapsed since 01/01/1979 and it was the basis of all calendar and date manipulation in the system. Take the date2num of a date, and apply a mod 7 and you could determine what day of the week it was for any date. By today's standards that seems kind of "big whoop" but in the days of CGA monitors and 360k floppy drives, being able to do this calculation accurately was a big deal.

So, flash forward to 2014. Some of that code from 1988 is now staring into the abyss of VB.NET. First, I needed to eliminate the dependency on a legacy 32-bit dll, namely qpro32.dll. That part was easy. In VB6 I already had figured out an all-code version of date2num, I can just use that! Right? Well... Not exactly.

Public Function Date2Num(ByVal strDate As String) As Integer
  If IsDate(strDate) Then
    Date2Num = Cint(CDate(strDate)) - 29220
  Else
    Date2Num = -32768
  End If
End Function

Pretty simple right? Convert a date to its raw visual basic internal format (elapsed days since 01/01/1900) and adjust it with a predetermined constant to make it based on 1979. Nope. VB.Net is strongly typed so my little trick of converting a date to its "raw" form fails miserably. To make a long story short, and probably nobody really cares all that much, here's VB.NET version of the same function.

 Public Shared Function Date2Num(ByVal strDate As String) As Integer
    If IsDate(strDate) Then
      Dim epoch As New DateTime(1979, 12, 31)
      Dim dt As DateTime = CDate(strDate)
      Dim ts As TimeSpan = dt.Subtract(epoch)
      Date2Num = ts.Days
    Else
      Date2Num = -32768
    End If
  End Function

So there you have it. date2num ported to VB.NET. Tomorrow, maybe, I'll do the inverse function num2date.

Thursday, June 6, 2013

Handy OpenSSL Commands

To convert a certificate from PEM to DER:
  • openssl x509 -in cert.txt -inform PEM -out cert.bin -outform DER
To convert a certificate from DER to PEM:
  • openssl x509 -in cert.bin -inform DER -out cert.txt -outform PEM
To convert a key from PEM to DER:
  • openssl rsa -in key.txt -inform PEM -out key.bin -outform DER
To convert a key from DER to PEM:
  • openssl rsa -in key.bin -inform DER -out key.txt -outform PEM
Convert a PEM+KEY to PKCS12:
  • openssl pkcs12 -export -out client.pfx -inkey keyfile.txt -in cert.txt -certfile root.txt
Extract Private Key from PKCS12:
  • openssl pkcs12 -in client.pfx -nocerts -out keyfile.txt
Extract Public Cert from PKCS12:
  • openssl pkcs12 -in client.pfx -clcerts -nokeys -out cert.txt
Remove Password from Private Key:
  • openssl rsa -in keyfile.txt -out unpassworded.txt
Generate a client key:
  • openssl genrsa -out client.key 4096
Build a certificate request:
  • openssl req -key client.key -new -out client.req
Build a certificate request (advanced):
  • openssl req -new -newkey rsa:2048 -nodes -keyout key.txt -out certreq.txt -days 3650
Display Certificate Details:
  • openssl x509 -text -in cert.txt
Test a SSL Host w/certificate:
  • openssl s_client -connect your.ssl.site:443 -CApath c:\rootcerts -cert test.cer -key test.key


Thanks to the following internet sources for their contributions to this document


Thursday, March 28, 2013

Updating Firmware on legacy Dell Hardware in Ubuntu Linux

It took a bit of Google searching and hocus-pocus to figure out how to patch the BIOS rev A04 on our old Dell PowerEdge SC1420 Server. Here's the magic incantation.
############################################################
# Dell Firmware Update for Ubuntu Linux, on Legacy Hardware
############################################################

# Install firmware update tool out of the universe repository

apt-get install firmware-addon-dell

# Not sure if this is needed, I didn't need it, but it's documented

modprobe dell_rbu

# Dump a list of all device ids in the system

bootstrap_firmware -a

# open http://linux.dell.com/repo/firmware/bios-hdrs in a browser
# search for IDs that appear in bootstrap_firmware output 
# In my case, the SC1420 is system_bios_ven_0x1028_dev_0x0173

wget http://linux.dell.com/repo/firmware/bios-hdrs/system_bios_ven_0x1028_dev_0x0173_version_a04/bios.hdr

# Queue the new bios to be updated durning the next warm-boot

dellBiosUpdate -u --force-mono -f bios.hdr

# You have to do a warm-reboot. power cycle will not work.
# The way the update works is that it loads the image into RAM and sets a CMOS bit. 
# The BIOS notices the bit and scans RAM for the image.

reboot