Load or Reload a LaunchAgent from installer script

Apple has some restrictions in place to prevent access to LaunchAgents running in a user session context.

But you may want to load or refresh a LaunchAgent as part of your install without requiring the user to log out and back in.

I prefer not to require logouts and reboots in my installation packages.  Where possible, I use munki’s unattended option so software installs silently and the user is not prompted.

After some experimentation, I came up with this hacky method of getting a LaunchAgent to load from a package being installed as root.  If you have a cleaner way to accomplish this, please let me know.  Update: Please see Per Olofsson’s comment for a much better method until I update this gist.

 

Triggering a shell script from MySQL

Sometimes you need to trigger a script when data changes in mysql.  Sometimes there just aren’t other hooks into the system and the database is your last resort.

It seems like this would be a common use case with a simple solution, but no.

MySQL does support triggers.

However what you can do inside a trigger is limited to what you can do in mysql.  This is good for security.

Using the following DOES NOT work!

\! /bin/ls >> /log/yourlog.txt

The !\ (bang or exclamation point + backslash) is a mysql console feature for running commands in the console.  These are ignored on the actual server.  Do not be fooled.  Since you are testing in the console, it will appear to work once, but the trigger will not cause your code to fire.

So you have two options:

1.) Polling

2.) MySQL UDF (plugin)

Polling

Yes, polling sucks.  But what you can do is still create a trigger that uses a separate (maybe in memory) table for capturing the changes.  Then your polling script only needs to look at that table to do its work.

So you could use something like this:

Create the temp_changes table (this example creates an in memory table):

CREATE TABLE temp_changes (changed_id INT, from_value VARCHAR(40), to_value VARCHAR(40)) ENGINE=MEMORY MAX_ROWS=500;

Create the mysql trigger:

DELIMITER $$
CREATE TRIGGER tg1 AFTER UPDATE ON `table_i_want_to_watch`
FOR EACH ROW
BEGIN
INSERT INTO temp_changes SET from_value = OLD.column_i_want_to_track, to_value = NEW.column_i_want_to_track, changed_id = NEW.id;
END $$
DELIMITER ;

The above will create a row in the temp_changes table with the old and new values and id of the column I want to track in the table I want to watch.  Substitute column_i_want_to_track and table_i_want_to_watch with your own table and column names.

Read the MySQL trigger documentation if you need to do something different.  This is just an example.

Now your external polling script can query only the temp_changes table without polling your whole database for changes.

MySQL UDF (plugin)

MySQL UDFs offer a powerful way to extend the functionality of your MySQL database.  But with great power comes great responsibility right?  (A. Yes.)

These plugins are written in C.  They need to be compiled and installed in your mysql plugins folder on the mysql server.

Plugins add custom functions you your mysql server.

Security is a major concern with this option because these functions run with the same privileges as the mysqlserver user.

There are a number of plugins published here including lib_mysqludf_sys, that will allow you to run shell commands.

Here is the justifiably scarey warning from that site:

Be very careful in deciding whether you need this function. UDFs are available to all database users – you cannot grant EXECUTE privileges for them. As the commandstring passed to sys_exec can do pretty much everything, exposing the function poses a very real security hazard.

Even for a benign user, it is possible to accidentally do a lot of damage with it. The call will be executed with the privileges of the os user that runs MySQL, so it is entirely feasible to delete MySQL’s data directory, or worse.

SQL injection takes on new meaning when the attacker can also run any command on your server.

So my recommendation is to download the source and modify it to hard code a specific path to the executable you want to run if you go this route. I was going to do this, but I’ve had to move on to other endeavors now.

Using the UDF plugin still involves using the mysql trigger functionality.  See Mike E’s solution on this stackoverflow post.

Get and use secure supported LDAP SASL authentication mechanisms

You don’t have to use insecure clear text Simple BIND authentication for accessing your LDAP servers.

Get list of supported authentication mechanisms:

ldapsearch -h example.com -x -b "" -s base -LLL supportedSASLMechanisms

Kerberos GSSAPI Example:

kinit
ldapsearch -v -Y GSSAPI -h example.com -b "DC=example,DC=com" "(sAMAccountName=someusername)"

DIGEST-MD5 Example:

ldapsearch -v -Y DIGEST-MD5 -h example.com -U someusername -R example.com -b "DC=example,DC=com"\
 "(sAMAccountName=someusername)"
Note: For Active Directory Digest Authentication to work, you may need to enable Reversible encryption on the account’s password and change the user’s password once.

Inspect Running Mac OS X Applications with F-Script

Objective C is a Dynamic Runtime, so you can load code like plugins during runtime. This dynamic runtime can be very useful for exploring what applications are doing. I use this to assess the security of applications for example.

F-Script provides an easy way to inject itself into a running app and explore around.

Download F-Script here

Launch the app you want to explore.

Then find the process id number of the app in a Terminal shell:

ps auxww | grep “App Name

Load the F-Script Framework into the app and insert its menu using:

sudo gdb --pid AppNameProcessID --batch --nx --command=/dev/stdin << EOT
p (char)[[NSBundle bundleWithPath:@"path/to/Library/Frameworks/FScript.framework"] load]
p (void)[FScriptMenuItem insertInMainMenu]
EOT

I found the above snippet by reviewing this automator service.

Note that sudo is only required if you are not in the _developer group.

At this point, switch to your running application.  You will notice an F-Script Menu is added to the menu bar.

Choose Console from the F-Script menu and type:

del := NSApplication sharedApplication delegate

This will give you a reference to the application delegate.  The application delegate is a top level class of the application, so it should provide a good starting point.

Next, choose Open Object Browser from the F-Script menu.

Now you should have a nice GUI window to explore the app.

Click on del in the Workspace to explore the app delegate.  You can call methods, change values, etc.

See the F-Script documentation for more details.

Enjoy