Skip to content

Instantly share code, notes, and snippets.

@tburgin
Last active August 29, 2015 14:24
Show Gist options
  • Save tburgin/fe424cac0d05e689e720 to your computer and use it in GitHub Desktop.
Save tburgin/fe424cac0d05e689e720 to your computer and use it in GitHub Desktop.
FV2 Add Users
#!/usr/bin/python
# Copyright 2015 Thomas Burgin.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import argparse, \
sys, \
os, \
plistlib
from OpenDirectory import kODRecordTypeGroups, \
kODRecordTypeUsers
from ctypes import *
from ctypes.util import find_library
from Foundation import kCFStringEncodingUTF8, \
NSArray, \
NSDictionary, \
ODSession, \
ODNode
libODFDE = CDLL(find_library('libodfde'))
libCSFDE = CDLL(find_library('libcsfde'))
coreFoundation = CDLL(find_library('CoreFoundation'))
class tCFString(Structure):
pass
tCFStringRef = POINTER(tCFString)
coreFoundation.CFStringCreateWithCString.restype = tCFStringRef
libCSFDE.CSFDEStorePassphrase.restype = tCFStringRef
class ODUserTool(object):
def __init__(self, user, password):
self.username = user
self.password = password
self.userODRecord = None
self.groupODRecord = None
def createTempAdmin(self):
mySession = ODSession.defaultSession()
node, _ = ODNode.nodeWithSession_name_error_(mySession, "/Local/Default", None)
self.groupODRecord, _ = node.recordWithRecordType_name_attributes_error_(kODRecordTypeGroups, "admin", None, None)
self.userODRecord, err = node.createRecordWithRecordType_name_attributes_error_(kODRecordTypeUsers, self.username, None, None)
if not (self.userODRecord):
sys.exit("Failed to create user [%s]\n%s" % (self.username, err))
print "Temp user [%s] created" % self.username
ret, err = self.userODRecord.changePassword_toPassword_error_(None, self.password, None)
if not ret:
sys.exit(err)
print "Temp user password set"
ret, err = self.groupODRecord.addMemberRecord_error_(self.userODRecord, None)
if not ret:
sys.exit(err)
print "Temp user added to the admin group"
def removeTempAdmin(self):
ret, err = self.groupODRecord.removeMemberRecord_error_(self.userODRecord, None)
if not ret:
sys.exit(err)
print "Temp user [%s] removed from the admin group" % self.username
ret, err = self.userODRecord.deleteRecordAndReturnError_(None)
if not ret:
sys.exit(err)
print "Temp user [%s] deleted" % self.username
def addUsers(usersList, od):
authUserName = coreFoundation.CFStringCreateWithCString(None, od.username, kCFStringEncodingUTF8)
authPassword = libCSFDE.CSFDEStorePassphrase(od.password)
ret = lambda userRef, passRef: libODFDE.ODFDEAddUser(authUserName, authPassword, userRef, passRef)
for e in usersList:
userToAdd = coreFoundation.CFStringCreateWithCString(None, e["Username"], kCFStringEncodingUTF8)
passwordToAdd = libCSFDE.CSFDEStorePassphrase(e["Password"])
if ret(userToAdd, passwordToAdd):
print "Added User [%s]" % e["Username"]
else:
print "Failed to add User [%s]" % e["Username"]
libCSFDE.CSFDERemovePassphrase(passwordToAdd)
def extract(plistIn, outList):
try:
outList.append({"Username":plistIn["Username"], "Password":plistIn["Password"]})
except KeyError:
pass
for key, value in plistIn.iteritems():
if isinstance(value, list):
for i in value:
extract(i, outList)
return outList
def main(argv):
## Run only as root ##
if not os.geteuid() == 0:
sys.exit("\nOnly root can run this script\n")
parser = argparse.ArgumentParser(description='Add Users to FileVault 2')
parser.add_argument('-plist', required=True, help='Path to a plist that contains usernames and passwords to add to FileVault 2.\
Plist should be in the same format as plists used with fdesetup.')
args = parser.parse_args()
try:
p = plistlib.readPlist(args.plist)
except IOError, e:
raise
## Define Temp Admin Username and Password
od = ODUserTool("gov.nih.fv2addusers", "Password123!")
od.createTempAdmin()
addUsers(extract(p, []), od)
od.removeTempAdmin()
if __name__ == "__main__":
main(sys.argv[1:])
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment