Tiny Deathstars of Foulness

Server comes with a command called RoomsAdminTool located at /Applications/ This tool can list available rooms using a -l flag:

RoomsAdminTool -l

You can also create new rooms, using the following format, where krypted is the name of the room, the persistent option means the room is, er, persistent. The description option indicates a description used for the room.

RoomsAdminTool -n krypted -c persistent yes description "This room is for friends of krypted only”

To then delete the room, use the -d option:

RoomsAdminTool -n krypted -d

Add the -v to do it all verbosely. There are lots of other options as well, as follows (from the man page): Valid Configuration Keys and Values:
descriptionstringA short description for the room
passwordstringDefine a password for room entry. An empty string implies no password required.
membersOnlyyes | noOnly room members are allowed to enter the room.
subjectLockedyes | noAre non-moderators and non-admins prevented from setting the room subject
logFormatDisabled | Text | XHTMLDisable room logging, or enable it using Text or XHTML.
maxUsersinteger; 0 for unlimitedSet the maximum allowed occupants for the room.
moderatedyes | no Make the room "moderated".
nonAnonymousyes | noIf "yes", only moderators/owners can discover occupants' real JIDs.
persistentyes | noPersistent rooms stay open until they are explicitly destroyed and their configuration survives service restarts, unlike non-persistent rooms.
privateMessagesAllowedyes | no Whether or not occupants can exchange private messages within the room.
roomPublicyes | no Defines whether the room be discovered by anyone
subjectstringSet a room subject/topic
usersCanInviteyes | no Defines whether occupants can invite other users to enter the room
addOwnervalid JabberIDMake the specified user a room owner (ex.: Rooms can have multiple owners.
removeOwnervalid JabberIDRemove the specified user from the room owner list
addAdminvalid JabberIDMake the specified user a room admin
removeAdminvalid JabberIDRemove the specified user from the room admin list
addMembervalid JabberIDMake the specified user a room member
removeMembervalid JabberIDRemove the specified user from the room member list
addOutcastvalid JabberIDMake the specified user a room outcast (banned from public rooms)
removeOutcastvalid JabberIDRemove the specified user from the room outcast list
Ultimately, if you’d like to do Student Information System (SIS) integration, or wait for an AD/OD group and then programmatically generate rooms, this is how you’d do it. Also, it’s worth noting that Messages (and so Jabber if you’re running your own server) is a very basic instant messaging tool. There are more modern ways of interacting with others these days, including Slack and Confluence. Additionally, the Messages app can just use the phone number of people to let address books become a way of managing groups you’d like to message. These do not require a dedicated server, but most strategies will require a monthly fee that’s typically per-user.

September 9th, 2017

Posted In: Mac OS X Server

Tags: , , , , ,

Wordpress has an app. That means there’s an API to normalize communication using a predictable programmatic interface. In this case, as with many others, that’s done using a standard REST interface to communicate. The easiest way to interact with any API is to just read some stuff from the server via curl. You can feed curl the URL to the API by using your URL followed by /wp-json – as follows, assuming a URL of curl To view header information: curl -s -D - -o /dev/null In the below example we’ll ask for a list of posts by adding /wp/v2/posts to the URL: curl You’ll see a list of some posts in the output along with a little metadata about the posts. You can then grab an ID and ask for just that post, using a post ID of 48390: curl You can also see revisions that have been made to a post by appending the URL with /revisions curl You can see comments with the comments route: curl Or pages with the pages route: curl Or users with the users route: curl Or media that has been uploaded with the media route: curl And the output of each can be constrained to a single item in that route by providing the ID of the item, which shows additional metadata about the specified item. And there are routes for categories, tags, etc. There’s also some good stuff at such as which is a plugin that allows you to auth against the API. curl --user admin:krypted Not only can you look at user information, you can also add and remove posts. You would add by doing a -X followed by a POST and then feeding a file with the –data option curl --user admin:password -X POST --data @post.json The output would then include the ID of your new post to wordpress. In the following example, we’ll get rid of the post we were looking at earlier using -X and DELETE in the URL, assuming a username of admin, a password of krypted, and a post ID of 48390: curl --user admin:krypted -X DELETE If successfully deleted the response would be as follows:
{ “message”:”Deleted post” }
To dig in deeper, check out where the whole schema is documented. You can also use the GitHub site to access a command called wp (as well as PHP, node, and java clients) that can be run at the command line for simple scripting interfaces. This could allow you to, for example, simply backup posts to json files, etc. Also, it’s worth noting that various plugins will require their own interface (note there’s no themes or plugins route), such as woocommerce, interfacing with or

July 14th, 2017

Posted In: WordPress

Tags: , , , , , , , ,

To tell curl that you can read and write cookies, first we’ll start the engine using an empty cookie jar, using the -b option, which always reads cookies into memory: curl -b newcookiejar If your site can set cookies you can then read them with the -L option curl -L -b newcookiejar The response should be similar to the following:
Reading cookies from file
Curl also supports reading cookies in from the Netscape cookie format, used by defining a cookies.txt file instead: curl -L -b cookies.txt If the server updates the cookies in a response, curl would update that cookie in memory but unless you write something that looks for a new cookie, the next use will read the original cookie again. To create that file, use the -c option (short for –cookie-jar) as follows: curl -c cookie-jar.txt This will save save all types of cookies (including session cookies). To differentiate, curl supports junk, or session cookies using the –junk-session-cookies options, or -j for short. The following can read these expiring cookies: curl -j -b cookie-jar.txt Use that to start a session and then that same -c to call them on your next use. This could be as simple as the following: CURL=/usr/bin/curl COOKIEJAR=cookie-jar.txt SITE= $CURL -j -b $COOKIEJAR $site You can also add a username and password to the initial request and then store the cookie. This type of authentication and session management is used frequently, for example in the Munkireport API, as you can see here: For converting, the -b detects if a file is a Netscape formatted cookie file, parses, then rewrites using the -c option at the end of a line: curl -b cookie.txt -c cookie-jar.txt

February 20th, 2017

Posted In: Mac OS X, Mac Security

Tags: , , , , , ,

When you’re regression testing, you frequently just don’t want any delays for scripts unless you intentionally sleep your scripts. By default Safari has an internal delay that I’d totally forgotten about. So if your GUI scripts (yes, I know, yuck) are taking too long to run, check this out and see if it helps: defaults write WebKitInitialTimedLayoutDelay 0 With a script I was recently working on, this made the thing take about an hour less. Might help for your stuffs, might not. If not, to undo: defaults delete WebKitInitialTimedLayoutDelay Enjoy.

February 1st, 2017

Posted In: Mac OS X Server, Mac Security

Tags: , , , , , , , ,

Dropping network connections can be incredibly frustrating. And finding the source can be a challenge. Over the years, I’ve found a number of troubleshooting methods, but the intermittent drop can be the worse to troubleshoot around. When this happens, I’ve occasionally resorted to scripting around failures, and dumping information into a log file to find the issue. For example, you may find that when a network connection fails, you have a very strong signal somewhere, or that you have a very weak signal on all networks. I’ve found there are three pretty simple commands to test joining/unjoining, and using networks (beyond the standard pings or port scans on hosts). The first is the airport command, along with –disassociate. This just unjoins all networks: sudo /System/Library/PrivateFrameworks/Apple80211.framework/Versions/A/Resources/airport --disassociate The second is a quick scan. Here, I’ve grep’d out the network I’m after (aka SSIDofNetwork – a very likely wireless network name), but when looking for environmental issues, you might choose to parse this into a csv and output all networks: sudo /System/Library/PrivateFrameworks/Apple80211.framework/Versions/A/Resources/airport -s | grep SSIDofNetwork Finally, you can join a network. You might have to escape out special characters in a password and it’s never wise to put a password into a script, etc. But, quick and dirty, this will join that SSIDofNetwork network: sudo networksetup -setairportnetwork en0 "SSIDofNetwork" mysecretpassword Anyway, loop it, invoke it however you invoke it, etc. Hope this helps someone, and if you have other tricks you’ve found helpful, feel free to throw them in the ‘ole comments!

How Users Feel About Intermittent Networking Issues

August 26th, 2016

Posted In: Mac OS X, Mac OS X Server, Mac Security, Network Infrastructure, Programming

Tags: , , , , , , ,

Posted a new swift command line tool to accept serial number data from an Apple device and respond with warranty information about a device at This is based on pyMacWarranty, at Screen Shot 2016-03-15 at 10.34.41 PM

March 16th, 2016

Posted In: Mac OS X, Mac OS X Server, Mac Security, Mass Deployment, Swift

Tags: , , , , , , , , ,

One of the options thats a tad bit hidden in OS X is the Secure Erase option, which runs a multi-pass erase on a volume. Additionally, there’s no option to Secure Erase free space on a volume. But you can still securely erase whatever you’d like (other than you boot volume obviously), when needed. To do so, use the diskutil command along with the secureErase option. Screen Shot 2016-01-07 at 7.44.07 AM The format of the command to secureErase freespace is:
diskutil secureErase freespace [level] [device]
The levels are as follows (per the man page as not all of these are specified in Disk Utility):
  1. Single-pass zero-fill erase
  2. Single-pass random-fill erase
  3. US DoD 7-pass secure erase
  4. Gutmann algorithm 35-pass secure erase
  5. US DoE algorithm 3-pass secure erase
So for example, let’s say you had a volume called Seldon and you wanted to do a standard Single-pass zero-fill erase. In this example you would use the following:
diskutil secureErase freespace 0 /Volumes/Seldon
If you were to automate the command then you would want to dump the output into a log file. For example:
diskutil secureErase freespace 0 /Volumes/Seldon > /var/log/secureeraselog.tmp
You can also secureErase a volume itself. To erase a volume called /Volumes/Seldon, use the same structure of the command, but this time without the freespace option: diskutil secureErase 0 /Volumes/Seldon The latest update to Disk Utility removes a lot of options from the GUI, but overall, I have yet to find a scenario where a task I need to perform isn’t still available, if only from the command line.

January 7th, 2016

Posted In: Mac OS X, Mac OS X Server, Mac Security, Mass Deployment

Tags: , , , , , , , ,

Pretty much every script I’m working on these days must be run as root. Checking what user is running something is pretty straight forward, as there’s a built-in shell variable for $USER that contains the user running a script. To see this real quick, simply run the following: echo $USER You can then put this into your scripts. I’ve been using the same block of code for decades, which can be run in a script by itself if you’d like to paste this into one. if [[ $USER != "root" ]]; then echo "This script must be run as root" else echo "You are root" exit 1 fi Note: Keep in mind that the built-in $USER variable is case sensitive. Obviously, most people won’t keep the lines that contain the else and you are root echo statements. You can just remove these or replace them with the meat of your script that requires elevated privileges to run. Enjoy.

December 21st, 2015

Posted In: Mac OS X, Mac OS X Server, Mac Security, Mass Deployment, Unix

Tags: , , , , , , , ,

Someone hands you a USB drive. You put it in your computer and you can’t access anything on it. You are running an imaging lab and you want to backup or troubleshoot a device before you re-image it, but you can’t access certain files. Obviously, you can sudo. But, you can also simply disable permissions on that volume (which, like getting someone to make you a sandwich, requires sudo of course). The command used to enable and disable permissions on a volume is vsdbutil, located at /usr/sbin/vsdbutil. And there’s a LaunchDaemon at /System/Library/LaunchDaemons/ that interacts with diskarbitrationd so that when a volume is mounted, it is marked as having permissions activated or deactivated (which is basically “Ignore Permissions” at the Finder). To use vsdbutil to enable “Ignore Permissions”, use the -d flag followed by the path to the volume: sudo /usr/sbin/vsdbutil -d /Volumes/Myvolume To then enable (or activate, thus the a) permissions again, use the -a flag: sudo /usr/sbin/vsdbutil -a /Volumes/Myvolume You can also run the -c to see the status for a given path: sudo /usr/sbin/vsdbutil -c /Volumes/Myvolume And last but certainly not least if you’re working on a lot of volumes, the -i option will enable permissions on all mounted HFS and HFS+ volumes: sudo /usr/sbin/vsdbutil -i Overall, it’s very easy to send these commands using a positional parameter (e.g. $1) to a script, performing a mount, some operation (backup, reimage, restore, repair some corrupted data, etc). Note: You can’t Ignore Permissions of FAT or FAT32 volumes using the command line or a Finder Get Info screen.

December 1st, 2015

Posted In: Mac OS X, Mac Security, Mass Deployment

Tags: , , , , , ,

The hostinfo command displays information about your host; namely your kernel version, the number of processors the kernel is configured for, the number of physical processors active, the number of logical processors active, the type of those processors, which ones are active, the amount of memory available, tasks, threads, and average load. Run hosting without any arguments or options: hostinfo The output would be as follows (ymmv per system): Mach kernel version: Darwin Kernel Version 15.0.0: Wed Aug 26 19:41:34 PDT 2015; root:xnu-3247.1.106~5/RELEASE_X86_64 Kernel configured for up to 4 processors. 2 processors are physically available. 4 processors are logically available. Processor type: x86_64h (Intel x86-64h Haswell) Processors active: 0 1 2 3 Primary memory available: 16.00 gigabytes Default processor set: 395 tasks, 1711 threads, 4 processors Load average: 1.78, Mach factor: 2.21 There are a bunch of other commands that can provide far more detailed information about your system. However, hostinfo has remained basically unchanged for 13 years, so if I can get something there, I can trust it’s fairly future-proofed in my scripts.

November 23rd, 2015

Posted In: Mac OS X

Tags: , , , ,

Next Page »