BlackBerry ‘Client’ Password

This is more for the programming geeks out there than anyone else. If you are looking for a quick and dirty way to store your BlackBerry username and password when using the BESUserAdminClient.exe, refer to the following document.

It allows you to simply pass a secondary password that will reference the credentials stored in the registry.

To set the password:

BESUserAdminClient -set_client_auth "-username ADU1 -password ADP1 -ad_auth -domain D1" -set_p password1

To access the credentials from the registry:

BESUserAdminClient -p password1

HMC Resource Management

Today I’m going to talk about the wonderful thing that is the Resource Manger for HMC (Hosted Messaging and Collaboration), the wondering framework from Microsoft for provisioning users for Exchange, OCS and SharePoint automagically.

Now, we tend to do things a bit differently at my current job. For example, I’m pretty sure I’m the only developer in the US that is hitting HMC (again, a Microsoft product) with PHP hosted on our linux based customer portal. That’s right, the Unix guys is the lead developer hitting a very Microsoft-centric product. Normally this would be done by a .Net developer.

So what does the Resource Manager give you? Well, the resource manager allows you to add, edit, remove mail databases for use on the system in the Exchange world which is what we are mainly going to focus on. When you first setup these resources, you set certain parameters for the mail stores. Do you want the domains on there to be tightPack or minStoreCount. TightPack attempts to use the smallest number of mail stores. MinStoreCount attempts to minimize the number of stores allocated to each org. We have gone with the minStoreCount model as we want to have all the users of the same domain live on the same store if possible.

Which is good in theory, but Microsoft has an extremely poor implementation of this.

Here’s an example. There is a domain on our system. The users used to live in 2 mail stores. We moved the users, through HMC calls, to all live in the same mail store. Now, when we create a new user, we do not specify the mail store. We rely on HMC and the resource manager to put the user in the correct location. Unfortunately, Microsoft drops the ball big time here. Instead of putting the user on the correct mail store with the other 30 accounts, it instead picks the old store that has no users on it. It fails to figure out that the mail store has been abandoned by that domain and continues to put users there.

Nice right?

So how do we get around this? Simple, write our own and tell them exactly where to put it. Yes, that’s right, recreating the wheel. Well all know we don’t need a rounder wheel. But in this case, we’re actually improving the functionality of the system.

I can’t go into the detail of how we actually implemented our system. But I can tell you, its already paying off by putting the users in the correct location.

But but but…is that it? Is that all you really solved? Do you really care if the users are spread out? Well, yeah, we do. We want them to be in the same mail store to help save on space for those messages that have the same attachment that went out to every users in the organization. Its not going to save you a ton of space, but it does save a lot more than you think it does.

But the placing of users isn’t the only improvement that we got from writing our own resource manager. One lacking feature of the resource manager is the ability to mark mailstores as non provisionable. I’m sure I’m going to get someone from Microsoft telling me that yes you can, there is a bit you can flip. And I’m here to tell you, they’re right, but they completely missed the boat on actual implementation.

It is true, you can mark a mail database as non provisionable. However, when you create a new user, HMC will ask which databases the domain lives on and picks one of them. note, it doesn’t query for all the databases that are provisionable, it asks for ALL of them for the domain. There is a chance, a very GOOD chance that HMC may automatically pick one of the stores that you have marked as not provisoinable. Awesome I know.

So how do you get around this little gem. Well, you can mess with the resource manager as we ran for a while. We had a script that would run daily and check a list of databases that we had marked to not have new users on them. Then it would check out the free space on the system and mess with the resource manager basically tricking the resource manager that it would be out of space. This had the same effect of not having new users allocated to it on the system as the resource manager would at least check to see if there was enough space on the database when putting a user on there. But even this had its drawbacks. For example, what if you have a system setup where you have plans in place where a user can have a 1GB, 2GB and 4GB mailbox. They have the 1GB plan and want to upgrade. Guess what, if the datastore doesn’t think that there is any more space on the drive, you you CANNOT upgrade them. Why in the world would you ever want someone to upgrade their account and spend more money with you. Crazy talk I know.

I’m sure you’re thinking, how in the heck did you ever come up with these crazy ways of mail database retirement. These suggestions came from Microsoft themselves. Even our premier tech support guy (who is awesome btw) didn’t know that these changes would cause such ass ache. Its like they never ran into a situation where someone would want to mark a database to not have any more new users allocated to it.

Our solution, write our own resource manager. not for the weak of heart, but I’m also not a pansy when it comes to this sort of thing. What we have done is put in place a system that keeps track of where each user, domain and mail store is located, how many users per store and where each domain lives. We can easily query this for the best place to put a user, but also the best place to put a user even if you have retired all the stores that the domain lives on, the system is smart enough to place the user on a new datastore for that particular domain. now when a new user is created, our provisioning system queries the resource manager, gets the appropriate store and we put that once “optional” parameter in HMC in the request XML and basically bypass the pile of shit resource manager that Microsoft has given us.

I’m sure that the big boys out there in this space will laugh at this post. I’m sure that they are way past where we are at. Or they have a bigger team that ran into this problem and put in their own solution. But if you happen to be starting out and are relying on the HMC resource manager, you might want to think again on that one. Eventually, you’ll write your own.

One Character == World of Suck

Ladies and Gentlemen, today you are going to learn a lesson on why you do NOT edit the active directory directly for exchange attributes.

Background
A long time ago, we had a very crappy provisioning system for our hosted Exchange 2003 platform. It worked ok, but missed a lot of things that we wanted to have set. They also were kind of pricks when it came to licensing so making a ton of money on the platform was hard to do. So, we decided to roll our own. It wasn’t that hard to reverse engineer what was being set for users, groups and contacts. There were a few obstacles of coarse but we were able to get a pretty good provisioning system setup. However, this too had its faults. Sure we had total control over the code and could update things as we needed. But we were still working in a void. We really didn’t know _everything_ that was happening on the system that needed to actually happen. Plain and simple, we were missing things. Not to mention future services would require the same amount of dev time reverse engineering what needed to be set. That’s not a scalable solution.

So, when it came time to roll out our Exchange 2007 environment, we have moved over to HMC and for the most part, things have been a lot happier.

The Issue
Since we have this shiny new 2007 platform, we thought it was in our best interest to start migrating our users from the 2003 platform and away from the old clunky provisioning. So far we have moved some smaller customers and everything has gone pretty smooth. Certain customers have required the migration to happen in stages so we have come up with a decent solution to make this as smooth as possible. We define the list of users to migrate, setup a temporary domain on the 2003 platform, add smtp aliases to the users on the 2007 platform and then enable forwarding on the 2003 platform to the 2007 temporary smtp alias. All mail still flows as it did before, its just that some users happen to be on the 2007 platform getting their email. Easy as can be right?

Well, the users that we have moved so far have been fairly small customers. So the need for automating certain aspects of the move have been put off. There is a lot of automation that happens, but some of the tasks were put off such as the setting of the forwarding address.

That is, until last week. Last week we were starting to move one of the bigger customers so I setup a script that would take the users that were being moved and automatically set the forwarding address. Here is the code that I had in place to figure out the forwarding address:

            // need to add forwarding address here.
            list($tuname, $tdmn) = explode("@", $user['mail']);
            // new address
            $fwd = "{$tuname}@{$newdomain}\n";

Notice the $fwd variable. This is where the trouble begins. You can ignore the {} as those simply tell the parser that these are valid variables contained within the string.

No, the real issue is at the end of the line. Specifically, the \n. Technically, you can set the AD object to whatever you want. It will take this as a value. However, Exchange does not like this. With forwarding in exchange, you set the forwarding to an object. Typically another user, group of contact. Since we allow for users to forward to multiple people, we create a group automatically and populate that with one or more users, groups or contacts.

Now for the really bad part. I’m not sure if this is just Exchange 2003 or if others are affected as well. But when you forward to a group that contains a single contact object that has invalid characters, your email message with be lost in the ether. Gone, Kaput, Not even an NDR will be generated. We were unable to even find logs that the message came in it failed that spectacularly.

Conclusion
So the moral of the story is, don’t do what we did. Microsoft will tell you the exact same thing. Its dumb to do what we did. You should not be messing with the AD attributes directly in this instance. There is a certain level of error checking that must take place at the upper levels which were missed by both my script, and the provisioning system. But in the same breath, I can’t say for sure that HMC was mature enough to use when we first rolled out the 2003 platform. So whether it is you editing AD directly or someone else doing it, its just as bad. It just depends on how much control you want over the gun pointed at your head.

No server restart?

I follow quite a few blogs of various people that make headlines and have a coding background. One person in particular that somehow made the list many moons ago that I have failed to remove is Leah Culver. I think it was her ties to the midwest and the fact that she seems to be putting her ass out there with Pownce (which has since had to close its doors).

In her latest post, she talks about writing a plugin for Django. If you are unfamiliar with django, it is a web framework written in python which loosely follows the model-view-controller design pattern (source).

Before I go on trashing the comments in the post, I’d like to note, I’m not a django developer and never have been. But I think that my overall points come back to good design and practices.

Ok, May I direct your attention to this comment made by Leah.

Let’s take the only advantage first, “can update on the fly, no server restart”. This is a web framework correct? Why the hell are you restarting!?!?! I’m clearly missing something here but for all the web apps that I have created, a restart isn’t required. A reload of my web browser is, but I’ve never had to restart my application or web server. I’m really not sure what she is referring to here exactly so I’m guessing I’m missing something major here. Maybe the application she is developing for requires an application server that needs to be restarted in which case it would make sense. But for some reason, I’m not thinking that is the case. Someone please explain this one to me in the comments.

In the disadvantages of using a DB, I have a big problem with #1, “slooooow”. If your database is slow, it is usually one of four issues:

  1. Bad Code/Database Design – This is usually where people screw up. Maybe they have never run an application where there are several million inserts in a day. Or maybe they’ve never seen the affects of table vs row level locking on updates. Maybe they don’t understand why their query doesn’t match any of the indexes that they have setup. The developer may not understand what an index even is! This is why developers and DBAs need to be on the same page in the database / code design. Even if you don’t have a DBA, there are plenty of web sites out there that can help you figure out how to tune your application and find slow points in your database code.
  2. Improper Database Tuning – This is where a skilled DBA can save your ass. If you don’t have one on staff, contract this out. There are consultants out there that are worth it. Find a good one, pay him his price and you will be amazed at what they can do. If you happen to have a development crew that is fanatical on code optimization and speed, they will probably make up for having a DBA on staff. But it never hurts even to bring a DBA in for a day or two, have him look at the DB, make some suggestions and turn it into a training session to help your developers grow.
  3. Database Load – Let’s face it, some databases are very large and have grown to the point where it is time to expand the design.
  4. Slow/Old DB Server – At a certain point, its not worth your time to spend weeks tweaking every query on a server that is 2-3 years old. Throw new hardware at it and let the improvements there increase your performance.

I don’t really have a major issue with the rest of her list, they all seem to be fairly logical. But I just didn’t understand the advantages fully and the first disadvantage, well, as you can tell it drove me up the freaking wall. If the database is slow, there is a good reason for it all of which are fixable.

Now, with all that being said, I do kind of agree with her. IF the data is not going to change, why store it in a database. Having a flat config file is not the end of the world people. Its fast, saves a query, and never changes! But that last part is pretty critical. If the data may expand which very well could in this instance, it proabably makes sense to put it in the database even though it doesn’t fully seem like it needs to go there. if you have your database design in order, you should be fine and never notice a performance hit getting this data.

Ugly Code

With my recent project, I had to do some research for the bits that make up the msRTCSIP-OptionFlags field in Active Directory for OCS users. There were certain operations that are not 100% supported by HMC so often times you have to fill in the gaps. The definition of this field is as follows:

This attribute specifies the different options that are enabled for the user or contact object. This attribute is a bit-mask value of type integer. Each option is represented by a bit. This attribute is marked for Global Catalog replication.

source

Unfortunately, in my searching I found not only the technet article, but I also found this

Here a sample of some of the code that you’ll find….

if strOptionFlag = "" then
objUser.Put "msRTCSIP-OptionFlags", "16"

else

‘If user not enabled then do not enable OCS
if strOptionFlag = "0" then
objUser.Put "msRTCSIP-OptionFlags", "0"
‘If user is enabled for Public IM then keep Public IM enabled and enable RCC
elseif strOptionFlag = "1" then
objUser.Put "msRTCSIP-OptionFlags", "257"
‘If user is enabled for RCC then keep RCC enabled and enable Enhanced Presence
elseif strOptionFlag = "16" then
objUser.Put "msRTCSIP-OptionFlags", "272"
‘If user is enabled for RCC and Public IM then keep RCC & PIM enabled and enable Enhanced Presence
elseif strOptionFlag = "17" then
objUser.Put "msRTCSIP-OptionFlags", "273"
‘If user is already enabled for RCC and Enhanced Presence then keep settings
elseif strOptionFlag = "272" then
objUser.Put "msRTCSIP-OptionFlags", "272"
‘If user is already enabled for RCC, PIM and Enhanced Presence then keep settings
elseif strOptionFlag = "273" then
objUser.Put "msRTCSIP-OptionFlags", "273"
end if
end if

All I have to say is wow! You’ve got to be freaking kidding me. Are there programmers out there that don’t understand what a bitfield is supposed to be or how to do bitwise operations? That’s like the first freaking class in a Computer Science degree. This is where you learn about Big 0, Binary numbers, loops, variables. If you are a programmer reading this blog and you don’t know what a bit field is and how to us it. Google it, read up, and rid the world of ugly ass code like what I found above.

Now technically what this person is doing would “work” since it is setting the integer with an appropriate number. But wow is this the WRONG way to do it. I’m afraid to see this persons code for when they need to check and see if the RCC bit is set for the user. Technically, they should be able to do a simple bitwise operation and check it something along the lines of:

if(($msRTCSIP-OptionFlags & 0x0010) != 0)
{
// RCC is set
}

I have a feeling that this person is doing for the following:

if(value == 273)
{
X is set
Y is set
Z is set
}
else if(value == 257)
{
Y is set
Z is set
}

This is a very simplistic psuedo-code example. But wow…I’m still in shock that this type of code is out there…and posted somewhat recently in October of 2008!

I really hope I run into this guy some day so I can beat him with the clue-by-4.