Wednesday, October 28, 2009

Squid on OpenBSD Gateway Firewall

Running Squid on an OpenBSD gateway firewall allows you a nice transparent client web proxy. Below are my notes for installation and configuration.

Installing


# pkg_add -v ftp://..../packages/i386/squid-2.7.STABLE6.tgz

Create the required swap directories

# squid -z

Start squid automatically upon boot. Add to /etc/rc.local

if [ -x /usr/local/sbin/squid ]; then
echo -n ' squid'; /usr/local/sbin/squid
fi


Configuration and File Locations

Configuration file (squid.conf) is located in /etc/squid

Log files (access.log*) are located in /var/squid/logs

Edit HTML error file (ERR_ACCESS_DENIED) is located in
/usr/local/share/squid/errors/English

Rotate the Squid log files once a day by adding the cron job. (sudo crontab -e)

0 0 * * * /usr/local/sbin/squid -k rotate

Redirect Rule for PF
rdr on $int_if proto tcp from $mynet to any port { 80 8080 } -> 127.0.0.1 port 3128

squid.conf settings

Network Settings
Port used by squid and mode (around line 930) http_port 127.0.0.1:3128 transparent

hostname for server (around line 3,000): visible_hostname mywebproxy.mydomain.net

Defining Access Lists (around line 500 of the squid.conf)

Remote domains
acl support.microsoft.com dstdomain support.microsoft.com
or for a list of domains in a text file (use .domain.com to get all sites in domain)
acl bad_sites dstdomain "/etc/squid/blocked_domains.txt"


Client IPs
acl labstation src XXX.XXX.3.3
acl local_net src XXX.XXX.3.0/24
or for a list of IPs in a text file
acl labstations src "/etc/squid/labstations.txt"

Destination IPs
acl badguy dst 156.17.17.19
or for a list of IPs in a text file
acl badguys dst "/etc/squid/badguys.txt"

Requested File Extensions
acl badfiletypes url_regex -i \.wmf$ \.exe$ \.zip$ \.bat$ \.msi$ \.vb$ \.vbs$ \.mde$ \.reg$

Client Access Rules (around line 650)
Rule logic is based upon first rule matching wins and allows or denies access

Allowing the safe_sites acl
http_access allow safe_sites

Denying the badfiletypes acl
http_access deny badfiletypes

Last two rules should allowing traffic for your clients acl and then block traffic from all others
http_access allow local_net
http_access deny all

Squid Commands

Reload the configuration file
# sudo squid -k reconfigure

Rotate the logs and cache
# sudo squid -k rotate

Wednesday, September 2, 2009

Powershell Script to Get All ActiveSync Devices

I wrote a quick Powershell script that will output an htm file of all the ActiveSync devices on an Exchange server. Just take off the .txt and using the Exchange Management Shell navigate to the directory where you have the script type in the command ./getactivesyncdevices.ps1 . The script will output the results to a file called getactivesyncdevices.htm.

$daysago = 7

@(

write-output '<html><head><title>Exchange 2007 ActiveSync Devices</title></head><body>'
write-output '<p><strong>Exchange 2007 ActiveSync Devices as of ' (get-date) '</strong></p>'
write-output '<p style="font-weight: bold; color: red;">Red = No Sync Attempts in ' $daysago ' Days</p>'
write-output '<table border="1" cellpadding="5"><tr><th>User</th><th>ActiveSync Device(s)</th></tr>'

$mailboxes = get-mailbox | sort -property name | select-object name,alias


foreach ($mailbox in $mailboxes)
{

$devices = get-activesyncdevicestatistics -mailbox $mailbox.alias


if ($devices -ne $null)
{

write-output '<tr><td>' $mailbox.name '</td><td>'

foreach ($device in $devices)
{


if ([datetime]$device.LastSyncAttemptTime -gt [datetime]::Now.AddDays(-$daysago) )
{

write-output '<p>'

}
else
{
write-output '<p style="font-weight: bold; color: red;">'
}

write-output 'ID:' $device.DeviceId '<br />'
write-output 'First Sync:' $device.FirstSyncTime '<br />'
write-output 'Last Sync:' $device.LastSuccessSync '<br />'
write-output 'Last Sync Attempt:' $device.LastSyncAttemptTime '<br />'
write-output 'Type:' $device.DeviceType '<br />'
write-output 'Model:' $device.DeviceModel '<br />'
write-output 'OS:' $device.DeviceOS '<br />'
write-output '</p>'
}

write-output '</td></tr>'
}
}

write-output '</table></body></html>'

) | out-file GetActiveSyncDevices.htm

Saturday, August 1, 2009

TCPDUMP Filter on OpenBSD PF Rule Number

Normally to see a current status of PF on OpenBSD you run the following:

$ sudo tcpdump -nettti pflog0

This will display all the traffic you're logging, however if you only want to view specific traffic from a certain rule you have to apply the rule number filter. Since tcpdump has access to the link-level header information, you can filter on the PF rule number.

First find out the rule number of the PF rule you want to filter on by running this command:

$ sudo pfctl -vvsr
(that is two v and not a w)

Then find the rule number of the desired PF rule and add it to your tcpdump command:

$ sudo tcpdump -nettti pflog0 rnr X


X = pfRuleNumber

Wednesday, July 22, 2009

OpenBSD MAC Filtering using a Bridge and Packet Tagging

A need came up for MAC address filtering on one of the networks I manage. The only way I know of filtering on MAC address is through the use of a bridge and pf packet tagging. At first I thought I would have setup a transparent bridging firewall in front of the gateway firewall; however, through the use of an additional network card and a bridge to nowhere I was able to accomplish this task.

Here is the setup:

Gateway firewall with three network cards
bge0 (external interface)
bge1 (internal interface)
re0 (monitor interface)

Standard gateway setup
echo 'inet xxx.xxx.250.194 255.255.255.252 NONE' > /etc/hostname.bge0
echo 'inet xxx.xxx.3.254 255.255.255.0 NONE' > /etc/hostname.bge1
echo 'xxx.xxx.250.193 ' > /etc/mygate

Then configure a bridge between the internal interface and the monitor interface. Added the bridge options to change the default MAC address cache size from 100 to 300 and to automatically load the bridge rules from a file.
echo 'up' > /etc/hostname.re0
echo 'add bge1 add re0 maxaddr 300 rulefile /etc/brrules.conf up' > /etc/bridgename.bridge0

The bridge rule file serves only one purpose, to assign a certain tag to all packets from a list selected MAC addresses. An example of the file can be found below. The tag applied to the packet stays with it even after it leaves the bridge and passes onto PF. This allows you to filter on it using PF. The tag is only internal to the system and won't travel over the wire. When using tagging on a bridge only the interface that is connected on layer 2 to the MAC address you want to tag can assign it.

Then you can simply use the tagged keyword in your egress pf rules to filter out the non-authorized traffic. Please note that you will have to create special rules for the IPs of the firewall so that it can get out.

# DNS out
pass out quick log on $ext_if proto { tcp udp } to any port { 53 } tagged goodmac label "dns out" queue std_bis

# Firewall DNS Out
pass out quick log on $ext_if proto { tcp udp } from $fw to any port { 53 } label "dns fw" queue std_bis

For services that require redirect rules (FTP and Squid) you will need to place the tagged keyword before the redirect assignment.

# FTP Redirect
rdr on $int_if proto tcp from $intnwk to any port 21 tagged goodmac -> 127.0.0.1 port 8021

# Squid Redirect
rdr on $int_if proto tcp from $squidies to any port { 80 8080 } tagged goodmac -> 127.0.0.1 port 3128

Below are some helpful brconfig commands for managing the bridge. I had to manually start the bridge the first time after initial setup but not so after numerous reboots.


I know this won't prevent someone from spoofing a MAC address but it will prevent the standard user from casually assigning a static IP on a non authorized system. If anything now I have a nice monitor port on the firewall for when the IT auditor shows up.

Load Rules File
$ sudo brconfig bridge0 rulefile /etc/brrules.conf

Flush Rules
$ sudo brconfig bridge0 flushrule bge1

View Loaded Rules
$ sudo brconfig bridge0 rules bge1

Add a New MAC into the Rules
$ sudo brconfig bridge0 rule pass in on bge1 src 00:13:72:3b:fc:f8 tag goodmac

Example of a Bridge Rule File
pass in on bge1 src 00:12:3f:76:96:dd tag goodmac
pass in on bge1 src 00:1e:2a:c2:ae:95 tag goodmac
pass in on bge1 src 00:19:d1:e5:af:f9 tag goodmac

Contents of /etc/bridgename.bridge0
add bge1 add re0 maxaddr 300 rulefile /etc/brrules.conf up

Display the Addresses Learned by the Bridge
$ sudo brconfig bridge0 addr

Manually Start the Bridge
$ sudo brconfig bridge0 up

Example of PF Rule Utilizing Tagging
pass out quick log on $ext_if proto tcp to any port 80 tagged goodmac label "Web Traffic"

PF: Packet Tagging
http://www.openbsd.org/faq/pf/tagging.html

brconfig
http://www.openbsd.org/cgi-bin/man.cgi?query=brconfig&sektion=8

Friday, July 10, 2009

Windows 2003 Firewall Program Exceptions for DPM 2007 and Exchange 2007

When utilizing the Windows 2003 firewall to protect both Data Protection Manager 2007 and Exchange 2007, I found that you have to make a few Inbound Program Exceptions on the firewall.

Here are the group policy firewall entries I had to make under "Inbound Program Exceptions"


DPM Server's Policy:

C:\Program Files (x86)\Microsoft DPM SRT\FileStore.exe:192.168.1.0/24:enabled:DPM FileStore.exe
C:\Program Files (x86)\Microsoft DPM SRT\rmtask.exe:192.168.1.0/24:enabled:DPM rmtask.exe
C:\Program Files\Microsoft DPM\DPM\bin\DPMRA.exe:192.168.1.0/24:enabled:DPM DPMRA.exe
C:\Program Files\Microsoft DPM\DPM\bin\msdpm.exe:192.168.1.0/24:enabled:DPM msdpm.exe



Exchange Server's Policy:
C:\Program Files\Microsoft Data Protection Manager\DPM\bin\DPMRA.exe:192.168.1.0/24:enabled:DPM Agent Exe
C:\Program Files\Microsoft\Exchange Server\bin\mad.exe:192.168.1.0/24:enabled:Exchange mad.exe
C:\Program Files\Microsoft\Exchange Server\bin\store.exe:192.168.1.0/24:enabled:Exchange store.exe


For the Exchange or any client server your trying to protect with DPM you will have to make the exception for the DPM Agent. You will also need to enable the "Allow inbound file and printer sharing exception" since these services utilize these ports as well.

Due to the way Group Policy processes, you might have to reboot your Exchange server twice for the program exceptions to process correctly.

Tuesday, July 7, 2009

Using .NET System.Management through Vista Firewall

In order to use .NET System.Management namespace against a remote Vista system, I had to enable a few settings on the remote system firewall. I made these changes via AD group policy. Here are the settings:


On the Firewall Group Policy, Created a new Inbound rule using the Wizard. Selected the Predefined Remote Administration set.



Enabled them for only my local subnet.




Then under the Network\Network Connections\Windows Firewall\Domain Profile settings of the group policy, enabled "Allow inbound remote administration exception". Then enabled that for only my local subnet.




Friday, June 26, 2009

Adding Ubuntu 9.04 Desktop to Windows 2008 Domain

As a present to one of my co-workers, I replaced his Vista system with Ubuntu 9.04 desktop. Below is how I added to my unit's Windows 2008 Active Directory. Please take note that you cannot add a computer object first and then reset it in AD.

Ran from a Terminal on the Ubuntu system:

sudo apt-get update
sudo apt-get install likewise-open
sudo domainjoin-cli join xxx.xxx.xxx yyyyyy

xxx.xxx.xxx = your fully qualified domain name
yyyyyy = domain admin user id

You will be prompted for the password of the domain admin account. Enter it and watch the fun. Reboot the system and login with xxx.xxx.xxx\userid.

As far as administrative privileges go, you can add an AD group or single account to sudeors on the Ubuntu system. At the terminal type in the following command:

sudo visudo

Under the
privilege section add either an individual AD account or group by adding:

xxx\\userid ALL=(ALL) ALL
%xxx\\groupid ALL=(ALL) ALL

xxx = YourDomain

Please note you will have to use the double back slashes.





Thursday, May 7, 2009

Wireshark Filters for OpenBSD's PF logs

By accident I found how to create a few Wireshark filters for OpenBSD PF logs.

View by PF Rule Number: pflog.rulenr == xx (where xx is the rule number)
View only Passed Packets: pflog.action == 0
View only Blocked Packets: pflog.action == 1
View by Network Interface: pflog.ifname == "xxxx" (name of the interface in ifconfig)

This should save me some time when going over the logs.

Thursday, April 16, 2009

Treadmill Platform

While on vacation the kids and I built a treadmill platform. Considering how much time I spend on my laptop or reading tech books this should really increase my cardio time. And the materials were under $40.00 (I already had the treadmill)



Friday, April 3, 2009

Disable Java Automatic Updates

I needed a way to turn off Java's automatic update feature on my Vista 64bit systems. I found this nice source link:

http://forums.sun.com/thread.jspa?threadID=5162382

but that's not the Java policy location in 64bit systems. You will have to configure the registry keys in

HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\JavaSoft\Java Update\Policy


"EnableJavaUpdate"=dword:00000000
"EnableAutoUpdateCheck"=dword:00000000


Created a nice group policy to do the trick. So now my clients won't complain about Java asking for updates.

Wednesday, April 1, 2009

Remote WMI (System.Management) and Wake on LAN in an ASP.NET C#

Below is a solution I came up with for a request of an ASP.NET site that would allow a network admin to perform basic admin actions on AD Windows systems. Using the System.Management and System.Net.Sockets namespaces I was able to create a site that allows a user to power on, reboot, and query info (Drive Size, Processer info, User Logged On, etc...) from those systems. I like to refer to it as my poor man's version of SMS.

Reference Links for C# Remote Command Line and Wake on LAN:

http://www.dalun.com/blogs/05.09.2007.htm
http://www.codeproject.com/KB/IP/cswol.aspx


-------------RWMI.aspx.cs-------------------
using System;
using System.Collections.Generic;
using System.Collections;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Net;
using System.Net.Sockets;
using System.Net.NetworkInformation;
using System.Data;
using System.Text;
using System.IO;
using System.Management;

public partial class RWMI : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
//Load DataTable and GridView with Demo System Info...Configure Application
//to Pull Real Data from Either SQL or Local Text File
//Column 0 = Computer Name
//Column 1 = IP Address
//Column 2 = MAC Address (Format xx:xx:xx:xx:xx:xx)

DataTable dt = new DataTable();

dt.Columns.Add("system", typeof(System.String));
dt.Columns.Add("ipaddress", typeof(System.String));
dt.Columns.Add("macaddress", typeof(System.String));

DataRow dr = dt.NewRow();
dr[0] = "System One";
dr[1] = "192.168.1.100";
dr[2] = "00:1c:23:53:e4:38";
dt.Rows.Add(dr);

DataRow dr1 = dt.NewRow();
dr1[0] = "System Two";
dr1[1] = "192.168.1.101";
dr1[2] = "00:b0:d0:07:6f:e0";
dt.Rows.Add(dr1);

gvComputers.DataSource = dt;
gvComputers.DataBind();

}

protected void CheckStatus(object sender, GridViewRowEventArgs e)
{
//Upon Databound Event, Ping IP to See If It's Up...Disable Power On Button
//If Not Then Disable Restart and Info Buttons

if (e.Row.RowType == DataControlRowType.DataRow)
{
Button btn = new Button();
btn = (Button)e.Row.Cells[3].Controls[0];

Button btn1 = new Button();
btn1 = (Button)e.Row.Cells[4].Controls[0];

Button btn2 = new Button();
btn2 = (Button)e.Row.Cells[5].Controls[0];

Ping pingSender = new Ping();
PingOptions options = new PingOptions();
options.DontFragment = true;
string data = "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb";
byte[] buffer = Encoding.ASCII.GetBytes(data);
int timeout = 120;
PingReply replyPing = pingSender.Send(e.Row.Cells[1].Text, timeout, buffer, options);

if (replyPing.Status != IPStatus.Success)
{
e.Row.CssClass = "NotGood";
btn.Enabled = true;
btn1.Enabled = false;
btn2.Enabled = false;
}
else
{
btn.Enabled = false;
btn1.Enabled = true;
btn2.Enabled = true;
}

}
}

protected void gvComputer_RowCommand(object sender, GridViewCommandEventArgs e)
{
try
{
//Finding Selected Row and Passing that Info to Function
int index = Convert.ToInt32(e.CommandArgument);
GridViewRow row = gvComputers.Rows[index];

//Creating Connection Options
ConnectionOptions coWMI = new ConnectionOptions();
//User Account Settings for Remote WMI Connection...Store Password in Web.Config for Better Security
coWMI.Username = "AdminUserID"; //AD Account That is an Admin on Local Systems
coWMI.Password = "AdminPassword"; //Password for that Account
coWMI.Authority = "NTLMDOMAIN:XXX"; //XXX is Your Domain

//Hide System Info Cell
tc2.Visible = false;

//Switch Statement for Button Command
switch (e.CommandName)
{
case "PowerOn":

TurnOnMAC(row.Cells[2].Text.ToString());
break;

case "Restart":

//Creates Remote Process on Selected System to Restart it in One Minute
ManagementScope msRP = new ManagementScope("\\\\" + row.Cells[1].Text.ToString() + "\\root\\cimv2", coWMI);
msRP.Connect();
ObjectGetOptions ogoRP = new ObjectGetOptions();
ManagementPath mpRP = new ManagementPath("Win32_Process");
ManagementClass mcRP = new ManagementClass(msRP, mpRP, ogoRP);
ManagementBaseObject inParams = mcRP.GetMethodParameters("Create");
inParams["CommandLine"] = @"shutdown /r /t 60";
ManagementBaseObject outParams = mcRP.InvokeMethod("Create", inParams, null);

break;

case "Info":

ArrayList alSoftware = new ArrayList();
ArrayList alDrives = new ArrayList();
ArrayList alProcess = new ArrayList();

//Setup Connection to Remote Systems root\cimv2
ManagementScope msWMI = new ManagementScope("\\\\" + row.Cells[1].Text.ToString() + "\\root\\cimv2", coWMI);
msWMI.Connect();

//WMI Query all Software Installed on System...Not Complete Listing...Only Software that writes to Certain Area in Registry
ObjectQuery oqSoftware = new ObjectQuery("Select Name from Win32_Product");
ManagementObjectSearcher mosSoftware = new ManagementObjectSearcher(msWMI, oqSoftware);
foreach (ManagementObject oReturn in mosSoftware.Get())
{
alSoftware.Add(oReturn["Name"].ToString());
}

alSoftware.Sort();
rptSoftware.DataSource = alSoftware.ToArray();
rptSoftware.DataBind();

//WMI Query for Computer Name, OS, RAM, and Last Bootup Time
ObjectQuery oqComputer = new ObjectQuery("Select * from Win32_OperatingSystem");
ManagementObjectSearcher mosComputer = new ManagementObjectSearcher(msWMI, oqComputer);
foreach (ManagementObject oReturn in mosComputer.Get())
{
lblComputerName.Text = oReturn["CSName"].ToString();
lblOS.Text = oReturn["Caption"].ToString() + " " + oReturn["CSDVersion"].ToString();
Decimal dRam = Convert.ToDecimal(oReturn["TotalVisibleMemorySize"].ToString());
dRam = dRam / 1000000M;
lblRam.Text = dRam.ToString("0.000") + " GBs";
lblBootTime.Text = ManagementDateTimeConverter.ToDateTime(oReturn["LastBootUpTime"].ToString()).ToString();
}

//WMI Query for Local Hard Drives...Calculate Free and Total Space
ObjectQuery oqDrives = new ObjectQuery("Select * from Win32_LogicalDisk WHERE DriveType=3");
ManagementObjectSearcher mosDrives = new ManagementObjectSearcher(msWMI, oqDrives);
foreach (ManagementObject oDrive in mosDrives.Get())
{
Decimal dFree = Convert.ToDecimal(oDrive["FreeSpace"].ToString());
dFree = dFree / 1073741824M;

Decimal dSize = Convert.ToDecimal(oDrive["Size"].ToString());
dSize = dSize / 1073741824M;

alDrives.Add("Drive: " + oDrive["DeviceID"].ToString() + " Free Space: " + dFree.ToString("0.00") + " GBs Total Size: " + dSize.ToString("0.00") + " GBs");

}
alDrives.Sort();
rptDisks.DataSource = alDrives.ToArray();
rptDisks.DataBind();

//WMI Query for Processor Information
ObjectQuery oqProcessor = new ObjectQuery("Select * from Win32_Processor");
ManagementObjectSearcher mosProcessor = new ManagementObjectSearcher(msWMI, oqProcessor);
foreach (ManagementObject oProcess in mosProcessor.Get())
{
alProcess.Add(oProcess["DeviceID"].ToString() + ": " + oProcess["Name"].ToString());

}
alProcess.Sort();
rptProcessor.DataSource = alProcess.ToArray();
rptProcessor.DataBind();

//WMI Query for Locally Logged On User...Will Display Admin Account If No One Logged On
ObjectQuery oqUsers = new ObjectQuery("Select * from Win32_ComputerSystem");
ManagementObjectSearcher mosUsers = new ManagementObjectSearcher(msWMI, oqUsers);
foreach (ManagementObject oUser in mosUsers.Get())
{
lblUser.Text = oUser["UserName"].ToString();
}


tc2.Visible = true;
break;

}
}
catch
{
Response.Write("Error Accessing System");
}
}

protected void TurnOnMAC(string macAddress)
{
//Wake On LAN...Take MAC Address (Format xx:xx:xx:xx:xx:xx)
//Convert to Byte...Send a UDP Packet to Wake Up System

UdpClient client = new UdpClient();
client.Connect(IPAddress.Broadcast, 40000);

Byte[] datagram = new byte[102];

for (int i = 0; i <= 5; i++)
{
datagram[i] = 0xff;
}


string[] macDigits = macAddress.Split(':');

for (int i = 1; i <= 16; i++)
{
for (int x = 0; x < 6; x++)
{
datagram[i * 6 + x] = (byte)Convert.ToInt32(macDigits[x], 16);
}
}

client.Send(datagram, datagram.Length);

}

}

--------------------Portion of RWMI.aspx--------------------------------

< p> < strong> Remote WMI (Windows Systems Only)< /strong> < /p>

< asp:Table ID="tb1" runat="server" CellSpacing="5">
< asp:TableRow>
< asp:TableCell ID="tc1" VerticalAlign="Top" runat="server">
< asp:GridView ID="gvComputers" runat="server" SelectedIndex="0" Font-Size="Small" AutoGenerateColumns="false" OnRowCommand="gvComputer_RowCommand" OnRowDataBound="CheckStatus" CellPadding="5" BorderWidth="2" GridLines="Both" >
< Columns>
< asp:BoundField DataField="system" HeaderText="Computer Name" />
< asp:BoundField DataField="ipaddress" HeaderText="IP Address" />
< asp:BoundField DataField="macaddress" HeaderText="MAC Address" />
< asp:buttonfield buttontype="Button" commandname="PowerOn" text="Power On"/>
< asp:buttonfield buttontype="Button" commandname="Restart" text="Restart"/>
< asp:buttonfield buttontype="Button" commandname="Info" text="Info"/>
< /Columns>
< /asp:GridView>
< /asp:TableCell>
< asp:TableCell ID="tc2" VerticalAlign="Top" Visible="false" runat="server">

< table cellpadding="5" cellspacing="2" border="2">
< tr> < td> < strong> Computer Info for < asp:Label ID="lblComputerName" runat="server" /> < /strong> < /td> < /tr>
< tr> < td> < strong> Logged On User:< /strong> < asp:Label ID="lblUser" runat="server" /> < /td> < /tr>
< tr> < td> < strong> Last Bootup Time:< /strong> < asp:Label ID="lblBootTime" runat="server" /> < /td> < /tr>
< tr> < td> < strong> OS:< /strong> < asp:Label ID="lblOS" runat="server" /> < /td> < /tr>
< tr> < td> < strong> RAM:< /strong> < asp:Label ID="lblRam" runat="server" /> < /td> < /tr>
< tr>
< td> < strong> Processor(s):< /strong> < br />

< asp:Repeater ID="rptProcessor" runat="server">
< ItemTemplate>
< %# Container.DataItem %>
< /ItemTemplate>
< SeparatorTemplate>
< br />
< /SeparatorTemplate>
< /asp:Repeater>
< /td>
< /tr>

< tr>
< td> < strong> Local Disk(s):< /strong> < br />

< asp:Repeater ID="rptDisks" runat="server">
< ItemTemplate>
< %# Container.DataItem %>
< /ItemTemplate>
< SeparatorTemplate>
< br />
< /SeparatorTemplate>
< /asp:Repeater>
< /td>
< /tr>

< tr>
< td> < strong> Installed Applications:< /strong> < br />

< asp:Repeater ID="rptSoftware" runat="server">
< ItemTemplate>
< %# Container.DataItem %>
< /ItemTemplate>
< SeparatorTemplate>
< br />
< /SeparatorTemplate>
< /asp:Repeater>
< /td>
< /tr>
< /table>
< /asp:TableCell>
< /asp:TableRow>
< /asp:Table>


Wednesday, March 11, 2009

Adobe Reader 9.1 .msi without Air.com

Found a way of creating an Adobe Reader 9.1 .msi that won't install Adobe Air.com

Here are the steps:

  1. Download the Adobe Reader 9.1 .exe installer from the Adobe FTP site


  2. Run this command:
    AdbeRdr910_en_US.exe -nos_o"Reader9" -nos_ne
    via the command line against the 9.1 installer to exact only the files and place them into a folder called Reader9 (very important see below)


  3. Using the Adobe Customization Wizard (available on the Adobe Enterprise Deployment site) configure a .mst using the .msi with the options you would like for the install


  4. Place the Reader9 folder (must be named that to not install Adobe Air.com) to a shared location and either configure a group policy or script to run the .msi

Friday, January 2, 2009

Configuring ASP.NET to use Integrated Security

Below are the steps for configuring Integrated Security for a ASP.NET application. These instructions are for Windows 2003 systems, one running IIS and the other SQL Server 2005.

  1. On the Web Server, Right Click My Computer and select Manage

  2. On the Computer Management Window, expand the Local Users and Groups menu item

  3. Right Click the Users folder and select New User

  4. On the New User window, enter the information for the local account. (Remember to uncheck the “User must change password at next logon” checkbox). Click
    Create

  5. Back on the Computer Management window, right click the local account and select
    Properties. On the Member of tab, click Add

  6. On the Select Groups window, ensure that the From this Location field is the name of the Web Server then click the
    Advanced button

  7. On the next window, click Find Now. Select the IIS_WPG group and then click
    OK. Click OK again to save the settings

  8. Grant the newly created local account Modify access to the C:\WINDOWS\Temp folder

  9. In IIS, expand the Application Pools menu. Either create a new application pool or right click an existing one. Select
    Properties and then the Identity tab

  10. Select Configurable then Browse for the newly created account and enter the password twice for the account. Click
    Apply and then OK

  11. On the Directory tab of the Properties for the Website, in the Application Pool field select it to run using the application pool identified with the local account

  12. Repeat steps 1 through 4 to create a local account with the same User ID,Name, and Password on the SQL Server. This local account doesn’t need to a be a member of any groups

  13. Open SQL Server Management Studio

  14. Expand the Security menu for the server

  15. Right Click the Logins folder and select New Login

  16. Click the Search button and find the local account on the SQL server

  17. Map that account to the required database

  18. Grant the local account access to any tables or stored procedures