Category Archives: Uncategorized

Uncategorized

Scrum Master 101

meanscrubs

Uncategorized

Bring Out Yer Apps with Autopkg! (Maybe with a little help)

(Guest post by Allister Banks)

Working with modern tools in the ‘auto’(dmg/pkg) suite, it sure reinforces the old chestnut, ‘it’s turtles XML all the way down.’ The thing that struck me when first diving into using autopkg was that different product recipes could potentially have a good amount of similarities when they share common processors. One example is drag-drop apps that can be discovered with an ‘appcast’ URL, which, in my recollection, became common as the Sparkle framework gained popularity.

This commonality is exactly the type of thing sysadmins like myself seek to automate, so I built a few helper scripts to 1. discover what apps have appcast URLs, 2. generate the base download recipe, and further, the 3. pkg-building recipe that can use the download recipe as a ‘parent’, and the 4. munki or JSS recipes which can nest the pkg recipe in it. Recursivity is the new black.

screnshotsOfCode

Please do take a look if you feel you’ve got apps that folks haven’t built recipes for yet, and laugh at/use/fork my code as you see fit!

Uncategorized

How to Find the Build Version of a Mavericks Installer

(Guest post by Allister Banks)

We’re several years in to Apple distributing its installer through its (formerly with the ‘Mac’ prefix) App Store, which if you right-click the bundle you can show package contents, and then navigate to the packages involved in the install as part of an Electronic Software Distribution image(or InstallESD.dmg for short.) Guidance remains the same, however, regarding getting the proper version of the OS to reinstall on your computer – in almost all cases, the newest hardware will only be supported by a ‘forked‘ version of the operating system. That means the process outlined here on Rich Trouton’s DerFlounder blog is still 100% applicable if you need to create and image with a tool like AutoDMG or perform a clean install for those models.

For the Lion releases of the OS, there was not really a functional difference between the InstallESD.dmg you’d find in the Install OS X {Mountain Lion,Lion}.app, and the old physical discs the installer was previously distributed on. Since the dmg was a bootable system unto itself, it had the normal complement of files with which you could query for what build it would install. In specific you could look at the same ProductBuildVersion key in the /System/Library/CoreServices/SystemVersion.plist file you’d find on any Mac(as of this writing, that number is 13B42 for most models released before the late 2013 Retina MacBook Pros and new MacPro.)

For the regular ‘universal’ builds (which would be listed here,) you can unflatten the OSInstall.mpkg you’d find in the Shared Support folder in the Contents folder within the app. (I have an automator service for expanding packages that may be of use to folks for this process, described here.)
Inside of the expanded OSInstall.mpkg you could open the Distribution file in your text editor of choice and look at the end of (currently) line three for the osBuildVersion value. (CreateOSXInstallPkg uses python’s minidom for this)

As of Mavericks, there’s a different directory structure inside the InstallESD.dmg, which confuses some folks who collect one for each of their forked models, and will need to continue to grab those specific builds from Internet Recovery for the foreseeable future. Fortunately, the only thing this new layout actually requires is a slight tweak to query:

PathFromMavsBaseSystemDMG

The actual dmg that gets dropped on the destination (to boot from) is there at the root, but hidden from the Finder when the InstallESD.dmg is mounted. Another way of navigating to it(besides turning on hidden files) is to run this command from the terminal after mounting InstallESD.dmg:

open /Volumes/OS\ X\ Install\ ESD/BaseSystem.dmg

Inside that BaseSystem.dmg there is the regular SystemVersion.plist at the path you’d traditionally find it, as mentioned above.

And there you go! Now you can make sense of all these InstallESD.dmg’s you’ve been stockpiling to serve the forked models in your fleet.

Uncategorized

Put wget On OS X

To install wget on a Mac, first make sure you have Xcode installed. Then, create a place to do your installation from:

mkdir ~/Desktop/wgetinstall; cd ~/Desktop/wgetinstall

Then, curl it down from the gnu.org ftp servers:

curl -O http://ftp.gnu.org/gnu/wget/wget-1.14.tar.gz

Next, extract the tar file:

tar xvf ~/Desktop/wgetinstall/wget-1.14.tar.gz

Then cd into the wget directory:

cd wget-1.14

And then let’s config:

./configure --with-ssl=openssl

Then a standard make:

make

Then a typical make install:

make install

Now let’s make sure we know where it went:

type -a wget

And now let’s test

wget —version

And to test downloading:

wget http://www.apple.com

Then, clean up after your installer:

rm -rf ~/Desktop/wgetinstall

Uncategorized

X-Men: Days of Future Past

Uncategorized

Configure A Mavericks File Server

File Services are perhaps the most important aspect of any server because file servers are often the first server an organization purchases. There are a number of protocols built into OS X Mavericks Server dedicated to serving files, including AFP, SMB and WebDAV. These services, combined comprise the File Sharing service in OS X Mavericks Server (Server 3).

File servers have shares. In OS X Mavericks Server we refer to these as Share Points. By default:

  • File Sharing has some built-in Share Points that not all environments will require.
  • Each of these shares is also served by AFP and SMB, something else you might not want (many purely Mac environments might not even need SMB). Or if you have iOS devices, you may only require WebDAV sharing.
  • Each share has permissions that Apple provides which will work for some but not all.

In short, the default configuration probably isn’t going to work for everyone. Therefore, before we do anything else, let’s edit the shares to make them secure. The first step is to create all of your users and groups (or at least the ones that will get permissions to the shares). This is done in Server app using the Users and Groups entries in the List Pane. Once users and groups are created, open the Server app and then click on the File Sharing service in the SERVICES list in the List Pane. Here, you will see a list of the shares on the server.

Screen Shot 2013-10-05 at 9.33.49 PMIn our example configuration we’re going to disable the built-in share. To do so, click on Groups one time and then click on the minus button on the screen.

Screen Shot 2013-10-05 at 9.34.51 PMAs mentioned, shares can be shared out using different protocols. Next, we’re going to disable SMB for Public. To do so, double-click on Public and then uncheck the SMB protocol checkbox for the share.

Screen Shot 2013-10-05 at 9.37.14 PMWhen you’ve disabled SMB, click on the Done button to save the changes to the server. Next, we’re going to create a new share for iPads to be able to put their work, above and beyond the WebDAV instance automatically used by the Wiki service. To create the share, first we’re going to create a directory for the share to live in on the computer, in this case in the /Shared Items/iPads directory. Then from the File Sharing pane in Server app, click on the plus sign (“+”).

Screen Shot 2013-10-05 at 9.38.49 PMAt the browse dialog, browse to the location of your iPad directory and then click on the Choose button.

Screen Shot 2013-10-05 at 9.39.23 PMAt the File Sharing pane, double-click on the new iPads share.

Screen Shot 2013-10-05 at 9.40.06 PMAt the screen for the iPads share, feel free to edit the name of the share (how it appears to users) as it by default uses the name of the directory for the name of the share. Then, it’s time to configure who has access to what on the share. Here, use the plus sign (“+”) in the Access section of the pane to add groups that should be able to have permission to access the share. Also, change the groups in the list that should have access by double-clicking on the name of the group and providing a new group name or clicking on the plus sign to add a user or group.

Screen Shot 2013-10-05 at 9.40.47 PM

The permissions available in this screen for users that are added are Read & Write, Read Only/Read and Write. POSIX permissions (the bottom three entries) also have the option for No Access, but ACLs (the top entries comprise an Access Control List) don’t need such an option as if there is no ACE (Access Control Entry) for the object then No Access is assumed.

If more granular permissions are required then click on the name of the server in the Server app (the top item in the List Pane) and click on the Storage tab. Here, browse to the directory and click on Edit Permissions.

Screen Shot 2013-10-05 at 9.42.06 PMAs can be seen, there are a number of other options that more granularly allow you to control permissions to files and directories in this view. If you make a share a home folder, you can use that share to store a home folder for a user account provided the server uses Open Directory. Once a share has been made an option for home folders it appears in both Workgroup Manager and the Server app as an available Home Folder location for users in that directory service.

Once you have created all the appropriate shares, deleted all the shares you no longer need and configured the appropriate permissions for the share, click on the ON button to start the File Sharing service.

Screen Shot 2013-10-05 at 9.46.18 PMTo connect to a share, use the Connect to Server dialog, available by clicking Connect to Server in the Go menu. A change in Mavericks is that when you enter an address, the client connects over SMB. If you’d like to connect over AFP, enter afp:// in front of the address and then click Connect.

The File Sharing service can also be controlled from the command line. Mac OS X Server provides the sharing command. You can create, delete and augment information for share points using sharing. To create a share point for AFP you can use the following command:

sharing -a <path> -A <share name>

So let’s say you have a directory at /Shares/Public and you want to create a share point called PUBLIC. You can use the following command:

sharing -a /Shares/Public -A PUBLIC

Now, the -a here will create the share for AFP but what if you want to create a share for other protocols? Well, -F does FTP and -S does SMB. Once created you can disable the share using the following command:

sharing -r PUBLIC

To then get a listing of shares you can use the following command:

sharing -l

You can also use the serveradmin command to manage file shares as well as the sharing service. To see settings for file shares, use the serveradmin command along with the settings option and then define the sharing service:

sudo serveradmin settings sharing

Sharing settings include the following:

sharing:sharePointList:_array_id:/Users/admin/Public:smbName = "administrator's Public Folder"
sharing:sharePointList:_array_id:/Users/admin/Public:nfsExportRecord = _empty_array
sharing:sharePointList:_array_id:/Users/admin/Public:afpIsGuestAccessEnabled = yes
sharing:sharePointList:_array_id:/Users/admin/Public:isIndexingEnabled = no
sharing:sharePointList:_array_id:/Users/admin/Public:dsAttrTypeNative\:sharepoint_group_id = "35DF29D6-D5F3-4F16-8F20-B50BCDFD8743"
sharing:sharePointList:_array_id:/Users/admin/Public:mountedOnPath = "/"
sharing:sharePointList:_array_id:/Users/admin/Public:dsAttrTypeNative\:sharepoint_account_uuid = "51BC33DC-1362-489E-8989-93286B77BD4C"
sharing:sharePointList:_array_id:/Users/admin/Public:path = "/Users/admin/Public"
sharing:sharePointList:_array_id:/Users/admin/Public:smbIsShared = yes
sharing:sharePointList:_array_id:/Users/admin/Public:smbIsGuestAccessEnabled = yes
sharing:sharePointList:_array_id:/Users/admin/Public:afpName = "administrator's Public Folder"
sharing:sharePointList:_array_id:/Users/admin/Public:dsAttrTypeStandard\:GeneratedUID = "4646E019-352D-40D5-B62C-8A82AAE39762"
sharing:sharePointList:_array_id:/Users/admin/Public:smbDirectoryMask = "755"
sharing:sharePointList:_array_id:/Users/admin/Public:afpIsShared = yes
sharing:sharePointList:_array_id:/Users/admin/Public:smbCreateMask = "644"
sharing:sharePointList:_array_id:/Users/admin/Public:ftpName = "administrator's Public Folder"
sharing:sharePointList:_array_id:/Users/admin/Public:name = "administrator's Public Folder"

To see settings for the services use the serveradmin command with the settings option followed by the services: afp and smb:

sudo serveradmin settings afp

AFP settings include:

afp:maxConnections = -1
afp:kerberosPrincipal = "afpserver/LKDC:SHA1.978EED40F79A72F4309A272E6586CF0A3B8C062E@LKDC:SHA1.978EED40F79A72F4309A272E6586CF0A3B8C062E"
afp:fullServerMode = yes
afp:allowSendMessage = yes
afp:maxGuests = -1
afp:activityLog = yes

To see a run-down of some of the options for afp, see this article I did previously. Additionally, for a run-down of smb options, see this one.

Uncategorized

CIDR Conversion Table

CIDR Conversion Table

CIDR prefix length

Dotted Decimal Netmask

Hexidecimal Netmask

Inverse Netmask

Binary

Number of Classfull Networks

Number of Usable IPs


/1 128.0.0.0 80 00 00 00 127.255.255.255 1000 0000 0000 0000 0000 0000 0000 0000 128 As 2,147,483,646
/2 192.0.0.0 C0 00 00 00 63.255.255.255 1100 0000 0000 0000 0000 0000 0000 0000 64 As 1,073,741,822
/3 224.0.0.0 E0 00 00 00 31.255.255.255 1110 0000 0000 0000 0000 0000 0000 0000 32 As 536,870,910
/4 240.0.0.0 F0 00 00 00 15.255.255.255 1111 0000 0000 0000 0000 0000 0000 0000 16 As 268,435,454
/5 248.0.0.0 F8 00 00 00 7.255.255.255 1111 1000 0000 0000 0000 0000 0000 0000 8 As 134,217,726
/6 252.0.0.0 FC 00 00 00 3.255.255.255 1111 1100 0000 0000 0000 0000 0000 0000 4 As 67,108,862
/7 254.0.0.0 FE 00 00 00 1.255.255.255 1111 1110 0000 0000 0000 0000 0000 0000 2 As 33,554,430
/8 255.0.0.0 FF 00 00 00 0.255.255.255 1111 1111 0000 0000 0000 0000 0000 0000 1 A or 256 Bs 16,777,214

/9 255.128.0.0 FF 80 00 00 0.127.255.255 1111 1111 1000 0000 0000 0000 0000 0000 128 Bs 8,388,606
/10 255.192.0.0 FF C0 00 00 0.63.255.255 1111 1111 1100 0000 0000 0000 0000 0000 64 Bs 4,194,302
/11 255.224.0.0 FF E0 00 00 0.31.255.255 1111 1111 1110 0000 0000 0000 0000 0000 32 Bs 2,097,150
/12 255.240.0.0 FF F0 00 00 0.15.255.255 1111 1111 1111 0000 0000 0000 0000 0000 16 Bs 1,048,574
/13 255.248.0.0 FF F8 00 00 0.7.255.255 1111 1111 1111 1000 0000 0000 0000 0000 8 Bs 524,286
/14 255.252.0.0 FF FC 00 00 0.3.255.255 1111 1111 1111 1100 0000 0000 0000 0000 4 Bs 262,142
/15 255.254.0.0 FF FE 00 00 0.1.255.255 1111 1111 1111 1110 0000 0000 0000 0000 2 Bs 131,070
/16 255.255.0.0 FF FF 00 00 0.0.255.255 1111 1111 1111 1111 0000 0000 0000 0000 1 B or 256 Cs 65,534

/17 255.255.128.0 FF FF 80 00 0.0.127.255 1111 1111 1111 1111 1000 0000 0000 0000 128 Cs 32,766
/18 255.255.192.0 FF FF C0 00 0.0.63.255 1111 1111 1111 1111 1100 0000 0000 0000 64 Cs 16,382
/19 255.255.224.0 FF FF E0 00 0.0.31.255 1111 1111 1111 1111 1110 0000 0000 0000 32 Cs 8,190
/20 255.255.240.0 FF FF F0 00 0.0.15.255 1111 1111 1111 1111 1111 0000 0000 0000 16 Cs 4,094
/21 255.255.248.0 FF FF F8 00 0.0.7.255 1111 1111 1111 1111 1111 1000 0000 0000 8 Cs 2,046
/22 255.255.252.0 FF FF FC 00 0.0.3.255 1111 1111 1111 1111 1111 1100 0000 0000 4 Cs 1,022
/23 255.255.254.0 FF FF FE 00 0.0.1.255 1111 1111 1111 1111 1111 1110 0000 0000 2 Cs 510
/24 255.255.255.0 FF FF FF 00 0.0.0.255 1111 1111 1111 1111 1111 1111 0000 0000 1 C 254

/25 255.255.255.128 FF FF FF 80 0.0.0.127 1111 1111 1111 1111 1111 1111 1000 0000 1/2 C 126
/26 255.255.255.192 FF FF FF C0 0.0.0.63 1111 1111 1111 1111 1111 1111 1100 0000 1/4 C 62
/27 255.255.255.224 FF FF FF E0 0.0.0.31 1111 1111 1111 1111 1111 1111 1110 0000 1/8 C 30
/28 255.255.255.240 FF FF FF F0 0.0.0.15 1111 1111 1111 1111 1111 1111 1111 0000 1/16 C 14
/29 255.255.255.248 FF FF FF F8 0.0.0.7 1111 1111 1111 1111 1111 1111 1111 1000 1/32 C 6
/30 255.255.255.252 FF FF FF FC 0.0.0.3 1111 1111 1111 1111 1111 1111 1111 1100 1/64 C 2
/31 255.255.255.254 FF FF FF FE 0.0.0.1 1111 1111 1111 1111 1111 1111 1111 1110 1/128 C 0
/32 255.255.255.255 FF FF FF FF 0.0.0.0 1111 1111 1111 1111 1111 1111 1111 1111 1/256 C 1
Uncategorized

Managing Windows Server 2012 Shares From Powershell

SMB cmdlets come in two modules. Before you can really use these in powershell you first need to import them. These are called SmbShare and SmbWitness, so to import the modules:

Import-Module SmbShare
Import-Module SmbWitness

Or for short:

Import-Module Smb*

Once the SMB modules are imported, we’ll start by looking at what shares you’ve got on your system using Get-SmbShare:

Get-SmbShare

Next, we can create a new share with the minimum two pieces of information required and adding who get’s FullAccess, which is not required:

New-SmbShare -Name BAK -Path E:BAK -FullAccess krypted

Then we can provide a little more information if we so choose. Here, I’m going to add a description to the share I just created:

Set-SmbShare -Name BAK -Description "To be used for Windows Backup backups."

Now that we have this BAK share, we can configure who’s able to access it. To see who can access the share, use Get-SmbShareAccess along with the -Name followed by the name of each share you’re curious about:

Get-SmbShareAccess -Name BAK

Note that this -Name structure is consistent with all the smb* cmdlets.

If we want to grant another user access to our share we can go ahead and do so using the Grant-SmbShareAccess cmdlet:

Grant-SmbShareAccess -Name BAK -AccountName krypted1 -AccessRight Full

Now that I’ve given the krypted1 user access to a share, I can remove the initial user krypted since I don’t really like him any more. To do so, use the Revoke-SmbShare cmdlet, again identifying the -Name of the Share followed by the account name to remove access for:

Revoke-SmbShare -Name BAK -AccountName krypted

You can also block a user from accessing a share. If a group is granted access and the user is blocked then the user will stay blocked. To block a user, use the Block-SmbShareAccess cmdlet, identify the -Name of the share and then the users name with the -AccountName option. That krypted user is kinda’ pesky so we’ll go ahead and block him:

Block-SmbShareAccess -Name BAK -AccountName krypted

But then the krypted user ends up needing access, so we’ll unblock him using the Unblock-SmbShareAccess cmdlet with the same syntax:

Unblock-SmbShareAccess -Name -AccountName krypted

Permissions are the next most important aspect of managing access to objects. Just because a user can access a share doesn’t mean they should be able to get into that juicy morsel of a payroll directory. CACLS is the command line interface to manage permissions at the file and directory level. CACLS is not a powershell cmdlet. You can see the permissions of a file or folder using the Get-Acl cmdlet. It’s just a cmdlet that you define a location to show the permissions for. Here, we’ll check the c:SharedPayroll directory:

Get-Acl c:SharedPayroll

Then, there’s the Set-Acl command, which can alter an Acl. As you can imagine, there are a lot of different permissions that can be applied to objects, including the need for recursion and for setting the permissions for recursed objects (OK, OK – I know recursed isn’t really what you might call that, but I’ve always wanted to say it so there ya’ go!). Therefore, instead of taking you through using set-acl I’ll just say, check out the TechNet on it at http://technet.microsoft.com/en-us/library/hh849810.aspx.

Finally, many environment just want the users who can access a share to have the Acl to access the data in the shares. To aid in what should be considered a relatively simple task, you can alter an Acl by piping the output of the get-SmbShare into the Set-Acl command. This sets the Acls to be the same as the permissions set in the share itself:

(Get-SmbShare -Name Bak).PresetPathAcl | Set-Acl

Uncategorized

Watchman Monitoring Sponsoring Krypted.com

150x150

I’d like to give  a big thanks to Watchman Monitoring for becoming the second sponsor of krypted.com. I like the fact that thus far, I’ve managed to keep all sponsorship talks within the Mac Admin community and hope this is a trend I can continue as time goes on. I also like the fact that it’s all products that I believe in! Watchman provides an excellent service, and if you haven’t had a chance to check it out then I encourage you to do so!

280x280

Mac OS X Mac OS X Server Mac Security Mass Deployment Uncategorized

Viewing Mac App Store Purchases From The Command Line

As you may have noticed, we’ve been working on building some links between the App Store and patch management tools such as Casper, FileWave and Munki. We’ve been looking at policy-based management of apps as well. In this semi-new world of signing and stores and the such, there’s actually a good bit you can ascertain about an app both inside the app as well as inside metadata OS X keeps about the app. I’ve discussed signing (apps and packages) in the past, but let’s look at using some commands to help us out with some tasks.

The first command is to determine some information about apps that are on the computer. Spotlight keeps a fair amount of information about these apps and can be invoked using the mdls command. Running the command with no additional parameters looks like this (I’m gonna’ use iMovie in these examples, although note that there are spaces in a lot of app names and paths as you start scripting things – so use IFS rather than trying to use traditional array):

mdls /Applications/iMovie.app

This results in output similar to the following (I’ve stripped out a few fields as they consume a lot of space and aren’t super pertinent to what I’m trying to do here):

kMDItemAlternateNames = (
"iMovie.app"
)
kMDItemAppStoreCategory = "Video"
kMDItemAppStoreCategoryType = "public.app-category.video"
kMDItemCFBundleIdentifier = "com.apple.iMovieApp"
kMDItemContentCreationDate = 2011-09-28 08:04:34 +0000
kMDItemContentModificationDate = 2012-09-22 02:13:45 +0000
kMDItemContentType = "com.apple.application-bundle"
kMDItemDisplayName = "iMovie"
kMDItemExecutableArchitectures = (
i386
)
kMDItemFSContentChangeDate = 2012-09-22 02:13:45 +0000
kMDItemFSCreationDate = 2011-09-28 08:04:34 +0000
kMDItemVersion = "9.0.8"

To just ask for one of these attributes, run the command along with the -name option in addition to the metadata attribute you’d like returned. For example, to see the bundle ID (kMDItemCFBundleIdentifier), use:

mdls /Applications/iMovie.app -name kMDItemCFBundleIdentifier /Applications/iMovie.app

Now, if you’d like to just quickly ascertain what apps on the system came from the App Store, use the mdfind command, along with whatever of the attributes matches what you want to know. Running mdfind for kMDItemAppStoreHasReceipt of 1 would look like the following and would result in a list of all apps on the system that came from the App Store:

mdfind kMDItemAppStoreHasReceipt=1

Blacklisting all apps that are part of a specific category (and with regard to customer requests, that category seems to always be Games) is something we get a lot of banter about with customers. To determine this information for apps, you can run mdfind on kMDItemAppStoreCategory for Games:

mdfind kMDItemAppStoreCategory=Games

You could then dump the contents of those into something that can blacklist apps (or whitelist based on other categories). Now, version control is another hot topic at various organizations. To see the version type of a given app, use the -name option with mdls kMDItemVersion

mdls /Applications/iMovie.app -name kMDItemVersion /Applications/iMovie.app

Then you can track the version of the app and take action through other ways to remove old versions and force users to upgrade. The mdfind command can also be leveraged to find apps that have escaped their traditional homes of /Applications and /Applications/Utilities, with the ability to obtain a full list by querying for kMDItemContentType of app bundles, as follows:

mdfind kMDItemContentType="com.apple.application-bundle"

Loading a list of apps (output from `mdfind kMDItemAppStoreHasReceipt=1` or `mdfind kMDItemAppStoreCategory=Games`) into an array and then querying each one of them for more information is pretty trivial beyond the steps we’ve already taken. This information can then be fed into some kind of Managed Prefs script to deny or allow access to various objects or an admin could even chmod the bundle, mark it as invisible, poison it (keep in mind, if you alter it you’ll break the signing), etc in order to get some desired outcome.

You can also use defaults to read a users com.apple.storeagent.plist file for the AppleID field to see what AppleID is currently logged into the AppStore, providing another variable that can be reported on:

defaults read /Users/cedge/Library/Preferences/com.apple.storeagent.plist AppleID

And yes, it’s worth noting that users from another account or a system image, etc can be used to download apps so this one isn’t exactly certain but the purchaser isn’t stored anywhere within the bundle nor is it permissioned in a way that we can use to find the purchaser that way.

There’s still a bit of a gap right now with regards to some of these technologies that Mac SysAdmins are managing. The consumeristic technologies such as App Stores are here to stay. We’re kidding ourselves if we think that we won’t be able to buy certain apps via Volume Licenses and have pkg installers for too much longer. Apple has made no indication that they’re dropping the results that can be obtained with a simple installer command, but with forcing signing on certain objects, gatekeeper and other technologies it’s hard to say what the future will really have in store for us. Getting to a point where we can report on elements of the App Store and hopefully eventually deploy objects through the App Store should continue to help bridge these factors, but I still see the need for additional binaries from Apple to be introduced to get the rest of the way there (or at least expose a method to me so I can go in there and buy an app through the method).