2012 in Review

Being the last day of 2012, I thought I'd take a minute and check out how I did with the goals I set for last year.

The big one was finishing my floor and moving back in. I had the ridiculous notion that it would have been done early in the year. They were basically finished the week before Thanksgiving, which is when I moved back home. So, while I did achieve the goal the time frame was WAY off.

  • Learn more C
    Achieved this goal. I was spending some time after work in the library and did advance some. I'd like to continue this in 2013
  • Use Blender to make a model and send to Shapeways to get fabricated
    Nope, didn't do anything here except install Blender
  • Arduino game of picking out states on map
    Got it started and bought parts, but still more work to be done
  • Get and use Eagle to make a simple PCB and have it fabricated
    Installed eagle and started working through the tutorials, but nowhere near ready to do a complete board.
  • Get a better understanding of how and when to use JSON
    Didn't do much with that.
  • Drawing lessons
    Nothing here
  • Piano lessons
    Didn't do anything here
  • Learn some basic statistics
    Nothing on this
  • Get started with GPU programming
    I can't do anything with this until I get a better grasp of C
  • Build a workbench
    Looked into buying some legs, but then didn't do it, so failed on this
  • Learn to weld
  • Work on a novel
    Nothing on this
  • Set up a Win7/Linux workstation for development work
    Installed a few linux virtual machines on my new laptop and could play around with them
  • Write up PDF on how to make linux as domain server and put it up for sale somewhere
    Nothing on this
  • Learn how to animate with Blender
    I got as far as installing Blender
  • Organize my tools/workspace
    I did move them all to the basement, but they're still a mess
  • Learn an alternative mail system to Sendmail
    Didn't do anything with this.
  • Go to some Ruby meetups
    Yep, did this. Went to some Ruby meetups
  • Pay for myself to go to a technical conference somewhere
    Yep, went to Windy City Rails
  • Make a dining room table and bench
    Nowhere near ready to start making furniture
  • Get my digital camera working with my telescope and go somewhere dark to see if I can get a good picture
    Not even on my radar over the year
  • Travel someplace that I’ve never been
    It's weak, but I did got to a park on my birthday that I never went to before. I'm sure I had something a bit more ambitious in mind when I wrote that down.

Kindle/iPad/ebook Reader Issue

I just purchased a book on Amazon to read on my ipad. Unfortunately, I have a number of different email addresses and I ended up using an email address that was different than the one I used to set up the Amazon app on my ipad. So the only way that I can read the book I just bought is to deregister the app with the old email, which will delete all the books that I currently have and then reregister with the new email address that I used. I did that and now have a single book in my ipad app, which is the one I just bought. If I want to get back the others, I have to repeat the process and go back to my old email address.

This is a fine example of why I dislike cloud services so much. If they would just let me download the damn books that I bought and handle saving them myself, I'd be fine. Yes, there's the possibility that I could accidentally delete a book that I bought. If that happened, I'd be upset with myself for being an idiot, but I could accept that and realize that I'd have to repurchase it if I wanted it again. With cloud services, I never feel like I have the books I bought. I'm just renting them and I don't like that idea.

Ebook readers are ok, but I'm still not an enormous fan of them. I don't buy many ebooks on Amazon (which is why I didn't realize I'd used a different email to register the app) and after this experience, I'm going to be much more wary in doing so. I will say that I buy a large number of ebooks having to do with computers and I fear I've become too accustomed to the treatment I've received from them. An fine example of a company doing things right is Pragmatic Programmers. There, I can buy an ebook and download a pdf file, which I use on my laptop. I can also download other formats that I can use to put the book on my ipad. It's really the best of both worlds and I'm a huge fan. Amazon, on the other hand, is someplace I'm planning on avoiding in the future, if possible.

Ruby and Ldap

I've been rewriting a script I use that lets people update their linux and samba user passwords at the same time. Our server uses samba and openldap to behave as a primary domain controller for our windows computers and a single sign-on for a few other services. It's been working great for years and way back when we started using this, I wrote a perl script to take care of keeping the two passwords in sync. The original problem was that if you use the regular linux passwd command, the linux password will change, but the samba one will not. The samba password uses an nthash. In a given user's ldap account, there is the userPassword field which holds the linux password and the sambaNTPassword field which holds the samba password. For a user to be able to use any of the web services we run on the server and login to any of our windows computers with the same password, these two fields need to contain the same password.

The solution however many years ago, was a perl script. I'm not much of a perl programmer, but I was able to hack something together that worked for years. However, each time that I upgraded the system, I'd have to install a few perl modules and it was always really difficult. If I were better at perl, this may not have been an issue, but it seemed to get more difficult each time I had to do it. It got to the point where I had a server with an older os on it where the script worked fine. I would direct people to log in to that server just to run the script to set the passwords. Thus, I finally decided that I should do something about this. These days, I do much more ruby on rails programming (though I'm still very much a beginner), so I figured this would be a good project to write in ruby. I found the net-ldap gem and was on my way.

The good news is that it didn't take me too long to set something up. I had a simple script that would let a user change their own password. However, the biggest use that my old perl script got was me using it to set an initial password for new accounts. Or, for me to reset a user's password after they forgot what it was. So I knew the next step was to write something that would let me (as the root user) change another user's password. This is my giant roadblock. I'm not an expert, but I've read the net-ldap docs and even looked at the code a bit. As far as I can tell, it does not support binding with one user's authentication and then updating a different user's attributes. Now, since I've been doing this for years with my perl script, I'm completely certain that I have my server set up properly. The issue has to be in the net-ldap gem. In fact, I've used the get_operation_result a lot and am pretty sure this is what's happening.

Here is the main method where I update a user's settings. I've edited it to make it as simple as possible and I've put in a bunch of print statements to see what's happening.

def change_password(logged_in_user, user_to_change, linux, samba)
    puts "USER TO CHANGE: #{user_to_change}"
    settings = user_settings(logged_in_user)
    conn = Net::LDAP.new(settings)
    puts "CHANGE_PASSWORD_BIND:  #{conn.get_operation_result.code}"
    puts "CHANGE_PASSWORD_BIND:  #{conn.get_operation_result.message}"
    conn.replace_attribute user_settings(user_to_change)[:auth][:username], :userPassword, linux
    puts "CHANGE_PASSWORD: #{conn.get_operation_result.code}"
    puts "CHANGE_PASSWORD:  #{conn.get_operation_result.message}"
    conn.replace_attribute user_settings(user_to_change)[:auth][:username], :sambaNTPassword, samba
    puts "CHANGE_PASSWORD: #{conn.get_operation_result.code}"
    puts "CHANGE_PASSWORD:  #{conn.get_operation_result.message}"

For a regular user changing their own password, the logged_in_user and user_to_change will be the same. But when I'm root trying to change someone else's password, this is not the case. Here's a sample of the output for when I try to update a user named arthur.

CHANGE_PASSWORD:  Insufficient Access Rights
CHANGE_PASSWORD:  Insufficient Access Rights

As soon as I try to run one of the replace_attribute commands, it tries to bind with that user's credentials. That will fail because I've collected the root user's password to use for authentication, not the user's password. As far as I can tell, this is by design. From the ruby-ldap docs:

User code does not need to call bind directly. It will be called implicitly by the library whenever you invoke an LDAP operation, such as search or add.

So, any bind I do doesn't matter because it's going to automatically bind with the replace_attribute call. And this call is going to use the dn for the user that I'm trying to fix, not the root user's dn.

I've spent all day at work and a good chunk of this evening trying to figure this out and I just think it's not designed to work as I'm expecting. So, what to do. Sometime next week, I think instead of using the net-ldap methods, I'll just run a system command that will run with the root binding. I think it's kind of funny that I tried to do this in ruby using the correct commands and I'm going back to how I did it in perl where I just run system commands with backtics. Anyway, if I ever get this working, I'm sure I'll post how I ended up doing it.

Hidden ~/Library Directory

Mac OS X 10.8 (I think 10.7 too) hides the user's Library directory by default. This is annoying. To automatically make in show in Finder, run this:

wc:junker $ chflags nohidden ~/Library/

And if for some reason you want it to be hidden again, do this:

wc:junker $ chflags hidden ~/Library/

Site Update

I had a little time yesterday so I updated the user interface for the colandheartless site. It didn't take too long and I'm very happy with how it turned out. The site is basically just serving up static webpages, so it's just some basic css/html. I did make all the pages php, but that's just so that I could put a function at the top of the page to display the header and navigation bar. It's really the only php that I know, but it's so handy that I use it all the time. Anyway, I wanted to update things so that I have slightly better organization for when I add new stuff. Specifically, I'd like to continually make pages that document the process of making the map game I've been thinking about and all the stuff that I've had to learn to be able to make the game. I could do this in the blog, but I'd also like to have a freer format for things than the blog provides. With the new site, I can pretty much do whatever I want.

One bad thing is that the theme of this blog is nothing like the theme for the rest of the site. So I may have to learn a bit more php so that I can create my own theme that will let me match the rest of the site. However, since that's not a big deal to me, it's way down on my list of things to do.

It Takes Time

I have, for the past few days, been immersing myself in adding parts to my arduino to extend functionality. There's a game involving a map that has been floating around in my head for a very long time. It's finally time for me to do something about it, so I'm starting to learn the things necessary to make it happen. I successfully hooked up a shift register to add a lot more leds, which will be necessary and now am hooking up a different type of shift register to add more buttons. This has proved a bit more difficult, but now, in my advanced age, I know that it takes time for things to sink in. Today was one of those great days where after struggling for a while, the light bulb went off over my head and I think I understand how things work.

Today's success has gotten me thinking about how I learn things. I'm very quick to buy books or videos to help me learn new things. Sometimes the books are helpful and sometimes they aren't. I used to just consider these things a crapshoot, but now I'm seeing a trend. I like it when I have working examples. I HATE it when problems are given, but no solution is provided. I know why the authors do that, so that people actually take the time to try to solve the problems, but it drives me nuts. The main reason is that, after struggling with something for days or weeks, I'd like to move on. But, since I can't solve the problem, I feel that I can't move on. The author has posed the problem because he or she thinks I should be able to figure it out at this point. The fact that I'm unable to makes me think I'm not ready to continue. But, I'm just spinning my wheels where I'm at. This is probably the number one reason that I quit working through a book or series. It's ok with me, if lots of examples are provided, but no problems are posed. If I'm working through the book, I must have a reason, so I can usually try to work through the problems I've come up with.

This past year, I've basically abandoned "Learn C the Hard Way" because there was a problem that I couldn't figure out and no solution was provided. I'd struggled with it for weeks and got nowhere. Clearly, there's a mental block I couldn't get through and needed some help. So, I bought a different book on C programming. One that's an actual college textbook. This one has been a lot more helpful and I'll probably stick with it for a while longer. Maybe, I'll go back to "Learn C the Hard Way" in the future, but I just find it incredibly frustrating when I get stuck. I guess I'll just have to see.

My recent studies have been more on using the arduino and the sample programs on their website have been invaluable. I tried reading the documentation and then writing programs on my own. Sometimes this worked, sometimes it didn't. When it didn't, it was incredibly helpful to see something working. And since some things had a few examples, I could see different ways people were using the command.

Anyway, today's success just reminded me that things take time to learn. As long as I keep remembering that and working on stuff, I'll usually understand things eventually, which is kind of cool.