Guest post: Checking user permissions on a Windows network
Posted on November 19th, 2008 | 11:58 AM
My friend Danny is a systems administrator and all-around IT guy at a manufacturing company in Indianapolis. He recently came up with a pretty useful little script, and wanted me to pass it on to the world.
Recently I needed to find out which folders a certain person was able to access on our Windows network. Apparently, this was extremely easy in Novell. Since it isn’t 1995 anymore, I tried to find a way to do this on the Internet. I couldn’t, so I set about making my own.
Microsoft has a utility called xcacls.vbs (if you’re using Vista, you’ll have to make sure WMI is installed, and modify the script. If you can’t do that comfortably, you probably don’t want to be messing with the rest of this anyway). It will allow you to change and view ACL’s from a command line. Since I’m not that interested in modifying the ACL’s in a script, the usage is fairly simple "xcacls c:\windows" will result in a listing of who has entries in the ACL and what the entry is (n.b. you’ll also have to have the default script host be cscript. Wscript won’t work).
In order for this to be useful, we really need to be able to have it run automatically on several, if not all, folders on a computer. The first step would be to get a list of the folders we want to run this on. I chose to limit it to one folder and all its subfolders only (c:\ will do everything, while c:\windows will only do the folders in c:\windows. If you want to do c:\windows and c:\program files only, you’ll have to run it twice).
What I was looking for was basically a text file that just had all the folders. This command will create exactly that:
dir "c:\program files" /s /b /o:gn /a:d > c:\batch\xcacls\dirlist.txt
Now that we’ve got a list of all the folders we need to search, we need to actually loop through it.
For /F "tokens=*" %%i in (dirlist.txt) do c:\batch\xcacls\aclSearch.bat administrator %%i
C:\batch\xcacls\aclSearch.bat is another batch file which takes two parameters (I’ll show you it in a minute). I call the other batch file so I don’t have to worry about how DOS handles variables (it doesn’t like to evaluate them during runtime, and will wait until the loop is done and use the final value for each iteration. It’s weird, I know).
A caveat about the for loop: when using for in an interactive CLI you use a single % sign in front of the i, when using it in a batch file, it’s a double %. Don’t ask me why.
aclSearch.bat contains the following
call c:\batch\xcacls\xcacls.vbs "%2" > c:\batch\xcacls\xcaclsResults.txt find /i %1 c:\batch\xcacls\xcaclsResults.txt if %errorlevel%==0 goto Found goto End :Found echo %2 >>c:\batch\xcacls\%1results.txt :End
This calls xcacls.vbs (from Microsoft) passing it the folder name. The quotes are there to handle filenames with spaces. It then sends the results into a temporary file called xcaclsResults.txt
Next we do a find using the search string (the first item passed – administrator in this example) on that file. If Find finds a match, the errorlevel is 0; if not, it is 1. If the errorlevel is 0, then the folder name is put into a results file named whatever the search string is, with results.txt appended (in this example it’d be administratorresults.txt).
So, how do you actually use all this? FindPermission.bat contains:
dir %1 /s /b /o:gn /a:d>"c:\batch\xcacls\dirlist.txt" for /F "tokens=*" %%i in (dirlist.txt) do c:\batch\xcacls\aclSearch.bat %2 %%i
To search the c:\program files directory for anything the administrators group has access to you’d type:
Findpermission.bat "c:\program files" administrators
The results will be in the same folder you ran findpermissons from and be called administratorsResults.txt. To search the C drive for anything Danny Parrott has access to, you’d need:
Findpermission.bat c:\ "Danny Parrott"
The results from this one will be in Danny Parrottresults.txt.
This does require that Findpermission.bat, aclSearch.bat, and xcacls.vbs be either in the same folder, or in a folder that’s in the path variable. It will work for either users or groups. This process is also not instantaneous. The xcacl.vbs script can take upwards of half a second to run, so on larger systems, this is something you’d want to start and come back to later. On the plus side, though, it hardly uses any system resources while running (5MB RAM and 2-4% CPU time on a four-year-old server at work) so you can run it during the day.
Filed under Guest Posts, Maximizing Windows, Software, Windows | No Comments »
Coldfusion 8 and Microsoft SQL 2005 : @@IDENTITY
Posted on November 12th, 2008 | 12:51 PM
There's a handy little query you can run in SQL to retrieve the identity (primary key) value of a record you just created. So, you can do something like this:
INSERT INTO
People (
Name
) VALUES (
'Joe'
);
SELECT @@IDENTITY AS NewName;
This query will create a new person and also return the identity value of the newly created record. It can be useful for all kinds of things - I use it frequently.
We recently upgraded to ColdFusion 8 here at Purdue, and my code started breaking.
It turns out that CF8 attempts to "help" you by automatically running SELECT @@IDENTITY after any INSERT query. This is problematic in two ways - it cancels out your own @@IDENTITY query, and it arbitrarily names the result Generated_Keys.
So instead of being able to do something like this:
<cfset TheNewName = People.NewName>
You must use this:
<cfset TheNewName = People.Generated_Keys>
It's really more annoying than anything else. It seems like a good idea to include the code automatically, but I think it would probably be a little better if there were a conditional in there that prevents CF8 from inserting its automatic query if a SELECT @@IDENTITY query is already present.
Filed under ColdFusion, Microsoft SQL, Web Development | No Comments »
When troubleshooting gets creative
Posted on October 29th, 2008 | 9:08 AM
I tend to be the go-to person for tech support among my friends, family, and neighbors. A few nights ago, one of my neighbors asked me to help him with his custom-built machine. His USB ports had mysteriously quit working. I messed around, and the same thing kept happening. His Microsoft USB wireless mouse worked just fine, but his HP all-in-one inkjet printer and his SanDisk thumb drive didn't work. Plugging them in resulted in a "one of the devices connected has malfunctioned" error from Windows. His thumb drive appeared to work just fine in Ubuntu Linux.
We removed all the USB host items from the Device Manager and reinstalled them, to no avail. Then I tried disabling the USB enhanced controller item (this is generally what lets Windows know that a USB controller is capable of USB 2.0). This worked, but kept his devices from working at USB 2.0 speeds. We even reinstalling Windows completely and still had the same problem.
I started Googling around and found this article regarding my exact problem - the SiS PCI to USB Enhanced Host Controller mysteriously quit working, and took all USB 2.0 devices down with it. This blogger's solution was to shutdown and unplug the computer, wait for about half an hour, hold in the power button for a minute, and then restart the machine.
And, like magic...it worked.
I can only begin to guess why. Like this other blogger, my neighbor's machine had a Gigabyte-brand motherboard. My theory is that something was getting corrupted or otherwise mistranslated by the motherboard regarding the USB 2.0 controller, and whatever was breaking things was being remembered across shutdowns and reboots.
By letting the machine sit for awhile, all the capacitors on the motherboard and power supply emptied out, thereby completely cutting power to the machine. This apparently reset whatever dark magic was causing the problem in the first place.
It's likely that in Matt's case, Linux was allowing the ports to work, but only at 1.1 speeds. Since we didn't test how quickly file transfers took place in Linux, I can't confirm this theory, but it would fit with my above assumptions.
At any rate, now we have our answer. The next time this happens (and I imagine it will), I'll try the fixes listed on usbman.com first, so we can try to cure the problem once and for all.
Filed under Hardware | No Comments »
OS X : VNC from the command line
Posted on October 27th, 2008 | 8:53 AM
Since OS X 10.4 (Tiger), Apple has provided a remote deskotp capability integrated into the operating system. However, unlike Windows (which uses a proprietary protocol called RDP), Apple chose to use the VNC protocol for their remote desktop server and client.
I wouldn't recommend using Apple's VNC server; it's far more restrictive than alternatives. Vine server is much more robust and customizable, and it's open-source.
However, if you find it necessary to use Apple's built-in VNC for whatever reason, you may also find yourself needing to control the server from the command line (for instance, if the server application fails and you need to SSH into your remote Mac to restart the service).
I found out the hard way that the Perl script Apple uses to restart the server stores the VNC password in plaintext. This is wrong on a lot of levels, one being that it's completely user-unfriendly. At any rate, after some Googling around, I found a Perl script that will encode the password with the necessary key. You can then input the encoded password in your VNC restart command.
The Perl script looks like this:
perl -nwe 'BEGIN { @k = unpack "C*", pack "H*", "1734516E8BA8C5E2FF1C39567390ADCA"}; \
chomp; s/^(.{8}).*/$1/; @p = unpack "C*", $_; foreach (@k) { printf "%02X", $_ ^ (shift @p || 0) }; print "\n"'
Paste this at your bash prompt and hit enter. You can then type your password, hit enter again, and have the encoded password ready to go. Once you have your encoded password, you can use the kickstart command to restart the VNC server. Apple has some documentation on using kickstart here.
Overall, Apple made a major blunder by not correctly encoding the password with the kickstart utility. I imagine it's just part of Apple's unwillingness to provide power users with real functionality. They're far more focused on their GUI than on command-line utilities such as this one.
Filed under OS X, Software | No Comments »
Whoops.
Posted on October 16th, 2008 | 4:15 PM
It's been more than a month since I last posted.
Sorry about that.
I'm going to be working on a new project that involves Twitter (likely in PHP, so that I can run it from ABetterGeek.com), so I may post some insights into that in the near future.
I don't intend for this to be a dead site; it's just hard to keep up with regular writing. I need more to talk about. Politics, maybe. And religion. And some lawyer jokes for good measure.
Filed under Personal Stuff | 2 Comments »
The many functions of useless hard drives…
Posted on September 13th, 2008 | 2:04 PM
I'm a bit of a packrat. When something electronic finally craps out, I tend to keep it around, just in case. Dead hard drives fall into this category, at least for me.
If you've never taken apart a hard drive, you should. The platters are unbelievably reflective, since they've never been touched by anything before being installed in the drive's casing. I have a large collection of hard drive platters at the moment, some of which have interesting radial patterns due to being scratched into oblivion by a misaligned head. I'm not sure what I'm going to do with them yet, but I'm sure I'll think of something.
Another handy component in a dead hard drive is its magnets. Hard drives have two extremely powerful magnets in them. You want to be careful when playing with these - you could injure yourself if you got some skin or a finger caught between two magnets as you snapped them together.
I use some magnets on my fridge - the ones that have prongs on one end work well for this, since it keeps the magnet itself from touching a surface. Hard drive magnets are strong enough that they're pretty difficult to pull off a magnetic surface.
So, in addition to my wide collection of hard drive platters, I also have around twenty hard drive magnets of varying sizes and styles. Today, I found a good use for one of them.
I live in an old historic house in downtown Lafayette, IN. All my walls are plaster. Today, I bought a cheap Black and Decker laser level at Menards. It comes with a magnetic wall mount, but the mount requires using a small pin to attach it to the wall. This pin only really works with drywall - if you've ever tried to push a pin or nail into plaster by hand, you know how difficult it is. So, I needed to find an alternative. Because of the design of the wall mount, I couldn't just stick it to the wall with a piece of double-sided heavy-duty tape. The solution? A hard drive magnet!
It worked perfectly. I used my favorite 3M indoor/outdoor double-sided tape to mount it to the wall. You need to be careful when using this tape - if you remove it too quickly, it will rip off a layer of paint. I would imagine that other types of adhesive mounts would work equally well - 3M's Command Adhesive tape would probably work, since the level isn't very heavy (at least, my $15 one isn't).
At any rate, think twice before dumping your trashed hard drives - they may still be useful for other geeky (and non-geeky) sorts of projects.
Filed under Hardware, Personal Stuff | No Comments »
JavaScript: Dynamic Form Element Names
Posted on September 7th, 2008 | 12:17 AM
Purdue, like a lot of enterprise-level organizations, uses LDAP to manage certain things. One of the advantages to LDAP is that it can provide information about users on a domain. Our organization uses some globally-accessible ColdFusion functions to quickly get user information based on user ID data.
With AJAX libraries and frameworks (we use Scriptaculous and Prototype), we've also created a bit of JavaScript that allows retrieving the first nad last name of a user from an entered ID without having to submit the form and post back to the page. It's a useful tool, but it was originally written to only work with one text field on a page.
In one of the applications I'm currently working on, I have several different fields that require this behavior. I decided to modify the script we have so that I could pass a value to the function as a sort of prefix. That way, I could have a text box with an ID of OwnerID, and another with an ID of UserID. Instead of the normal script, which is called just by lookupID(), I'd be able to refer to a specific input, using something like lookupID('Owner').
Everything was coming along the way I needed it to, until I got to the section of code that dealt with changing the values of input boxes on the form. When a user enters a person's ID, the JavaScript code looks up the person's first and last name and displays that name in a read-only input box on the page. Since each ID input box had a corresponding read-only input box, I needed to be able to dynamically refer to that box using the prefix passed to the function.
It's very easy to accomplish, but it took a bit of Googling to figure it out. It turns out that square brackets give us the ability to manage the task. For instance, for a form named "edit", the standard code might look something like this:
form.edit.OwnerName.value = '(' + FirstName + ' ' + LastName + ')';
However, the OwnerName input box ID needs to be different for each read-only box, so we use square brackets to create a dynamic form element reference, where foo is the prefix passed to the function:
form.edit.elements[foo + 'Name'].value = '(' + FirstName + ' ' + LastName + ')';
It's a bit more complicated than dynamic variable names in ColdFusion, but it's fairly easy to implement, and it gets the job done.
Dynamic variable names can be extremely useful when dealing with similar pieces of code, loops and other such concepts. Each language deals with it differently, but I've found it an important element to learn about in most of the applications I create.
Filed under JavaScript, Web Development | No Comments »
Google’s hostile EULA - how long can you avoid it?
Posted on September 3rd, 2008 | 2:11 PM
I, like pretty much everyone in the known Internet-accessible world, use Google. A lot. I've used Google Docs in the past, I have friends and family who only use Google Talk for chatting, Google is obviously the biggest and best search engine available, and now they have a browser.
A browser which, unfortunately, I will not be using.
There's an interesting article that lays out the details of Google's EULA (end-user license agreement). It's not pretty.
This has all come to light with the release of Chrome, but Google's user-hostile EULA has been around for much longer. The basic gist of it is that Google claims to have royalty-free license to use, manipulate, and/or modify any content (text, images, etc) that you send through their services.
What does this mean for you? Google's EULA stipulates that you confirm your legal right to any content you send - that it's your own intellectual property (IP). This just isn't possible, as the above article discusses. If you use your corporate webmail through Chrome, you have no right to give Google license to use any content sent through email. Your company holds all rights to that content - not you, not Google.
Is it possible to live without Google? Probably, but I'm not interested in giving it up as my search engine. I won't, however, be using Google's browser (although for other reasons as well, which I'll discuss in another article). I'll also be pretty cautious about using Google Docs to store any important content - I'd much rather put some kind of document management system on my own server, free of anyone's service or license agreements.
Google's started to get a little powerful for its own good. I applied for a job there in 2006 (when I was finishing my undergraduate studies at IUPUI), and they were pretty underhanded and unethical in how they handled the interview process. I was never explicitly informed that I was applying for a contract position with no guarantee of full-time salaried employment. I had to ask them directly about that - it's just not an honest way to do things. Aside from that personal experience, though, just look at how widespread Google has become. They've infiltrated many industries. They're talking about releasing a smartphone with an alternative to Windows Mobile and PalmOS. They're buying up other services to expand their reach. It's how capitalism works, but it this case, I think it's becoming a little dangerous.
Like Apple, people just trust Google to treat them well as customers and users. They trust Google to not abuse its power, and they believe that it has their individual best interests in mind. Unfortunately, that's just not how corporations work. Google is like any other corporation in that they are driven by what funds them - their stockholders. Google continues to provide good products, because it means people will be interested in their offerings and will consider buying their stock. But at the end of the day, it's not about your interests at all - it's about money and profit. Google is no better a corporation than Microsoft; it's just that the owners of Google aren't as upfront about their evil as Steve Ballmer is.
I started looking around for alternatives to some of Google's offerings. There's an interesting service provider called Zoho that seems to provide a lot of the same services without the hostile user agreement. In fact, Zoho is the complete opposite:
We respect your right to ownership of content created or stored by you. Unless specifically permitted by you, your use of the Services does not grant AdventNet the license to use, reproduce, adapt, modify, publish or distribute the content created by you or stored in your Account for AdventNet’s commercial, marketing or any similar purpose.
It used be that nobody read EULAs on software or services, because they all said the same thing - a disclaimer, limitation of liability, and rules about what's considered illegal and grounds for revocation of the license in question. Now, however, with Google's EULA coming under public scrutiny, it might be worth your time to make sure you haven't agreed to any license terms that no sane person should ever voluntarily agree to.
Filed under Internet News, Personal Stuff | No Comments »
Linode and sendmail
Posted on August 26th, 2008 | 12:51 PM
I would not have figured out all this if it hadn't been for someone on the #linode channel with the patience to walk me through the steps.
At any rate, when I moved abettergeek from Dreamhost to Linode, mail quit working in the forums. PHP has a built in mail() function, but it requires some server config to work - apparently, Dreamhost took care of that, while Linode's default Linux install doesn't have sendmail installed by default.
This makes sense - Linode basically allows you to select from a number of Linux distros, and they drop a very barebones image onto your VPS. It's up to you to install the things you need. This is better than, say, installing everything by default and leaving a bunch of ports and vulnerabilities open from the start.
sendmail, however, is a bit pickier than Apache when it comes to making it work properly. These steps are using Ubuntu 8.04 LTS, but they'll be similar for any Linux distro.
First, you'll want to actually install sendmail:
apt-get install sendmail
That part was easy...however, the default Ubuntu config did not have my hostname information configured properly. You'l need to update your hosts file and your hostname file:
sudo nano /etc/hosts
if you have a line that looks like 127.0.0.1 ubuntu, remove it. The top two lines of the file should look like this:
127.0.0.1 localhost 72.14.177.31 abettergeek.com
Then, you need to update your hostname file:
sudo nano /etc/hostname
This needs just one line for your domain
abettergeek.com
Restart your server for the changes to take effect, and you should be able to now send mail using the mail() function in PHP.
Filed under Software | No Comments »
Minor announcement
Posted on August 23rd, 2008 | 1:45 AM
In the unlikely event that anyone is reading this blog, things are going to go offline sometime in the near future, once GoDaddy finishes transferring my domain to my new registrar (aplus.net).
Lesson learned from this experience: GoDaddy sucks. A lot. Their interface is terrible, they only have long-distance phone support, the level of communication involving even doing this transfer was unbelievably bad, and I am never going to use them for anything again.
Filed under Personal Stuff | No Comments »