Last active
August 29, 2015 14:24
-
-
Save tburgin/fe424cac0d05e689e720 to your computer and use it in GitHub Desktop.
FV2 Add Users
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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