...
 
Commits (10)
...@@ -6,7 +6,9 @@ ...@@ -6,7 +6,9 @@
// Copyright © 2017 NoMAD. All rights reserved. // Copyright © 2017 NoMAD. All rights reserved.
// //
enum HintType: String { enum HintType: String, CaseIterable {
case migratePass
case migrateUser
case networkSignIn case networkSignIn
case noMADUser case noMADUser
case noMADDomain case noMADDomain
...@@ -18,6 +20,8 @@ enum HintType: String { ...@@ -18,6 +20,8 @@ enum HintType: String {
case uid case uid
case gid case gid
case kerberos_principal case kerberos_principal
case passwordOverride // stmop on the password
} }
// attribute statics // attribute statics
......
//
// DS+Okta.swift
// NoMADLoginOkta
//
// Created by Josh Wisenbaker on 9/20/18.
// Copyright © 2018 Orchard & Grove. All rights reserved.
//
import OpenDirectory
enum NoMADQueryErrors: Error {
case noMigrationCandidates
}
// MARK: - NoMAD extensions for the DSQueryable Protocol.
extension DSQueryable {
/// Check to see if a given local user has the `kODAttributeOktaUser` set on their account.
///
/// - Parameter shortName: The shortname of the user to check as a `String`.
/// - Returns: `true` if the user has an Okta attribute. Otherwise `false`.
/// - Throws: A `ODFrameworkErrors` or a `DSQueryableErrors` if there is an error.
public func checkForNoMADUser(_ shortName: String) throws -> Bool {
os_log("Checking for Okta username", type: .default)
do {
let userRecord = try getLocalRecord(shortName)
let names = try userRecord.values(forAttribute: kODAttributeADUser)
if names.isEmpty {
return false
}
return true
} catch DSQueryableErrors.notLocalUser {
return false
} catch {
throw error
}
}
/// Search in DSLocal and find any potential migration users.
///
/// - Parameter excludeList: An optional `Array` of `String` values to exclude from the candidate list. These are typically set in the `.MigrateUsersHide` preference key.
/// - Returns: The shortnames of the users to offer for Okta migration in an `Array` of `String` values.
/// - Throws: A `ODFrameworkErrors` or a `DSQueryableErrors` if there is an error. Throws `NoMADQueryErrors.noMigrationCandidates` if no results are found.
public func findNoMADMigrationCandidates(excludeList: [String] = [String]()) throws -> [String] {
do {
os_log("Checking for NoMAD migration users.", type: .default)
var candidates = [String]()
os_log("Getting all user records.", type: .default)
let records = try getAllNonSystemUsers()
os_log("Filtering records", type: .default)
let filtered = try records.filter({ (record) -> Bool in
if excludeList.contains(record.recordName) {
os_log("User is exluded", type: .default)
return false
}
if try checkForNoMADUser(record.recordName) {
os_log("User has a NoMAD Attribute", type: .default)
return false
}
return true
})
for record in filtered {
candidates.append(record.recordName)
}
if candidates.isEmpty {
throw NoMADQueryErrors.noMigrationCandidates
}
return candidates
} catch {
throw error
}
}
}
This diff is collapsed.
//
// LocalCheckAndMigrate.swift
// JamfConnectLogin
//
// Created by Joel Rennich on 2/19/19.
// Copyright © 2019 Jamf Inc. All rights reserved.
//
import Foundation
import OpenDirectory
enum MigrationType {
case errorSkipMigration // unable to complete migration
case fullMigration // perform full migration
case skipMigration // no need to migrate
case syncPassword // local password needs to be synced with local
case userMatchSkipMigration
case complete // all good
}
// class to handle local checks and migration
class LocalCheckAndMigrate : ContextAndHintHandling, DSQueryable {
var mech: MechanismRecord?
private var user = ""
private var pass = ""
public var migrationUsers: [String]?
func run(userToCheck: String, passToCheck: String) -> MigrationType {
user = userToCheck
pass = passToCheck
let migrate = (getManagedPreference(key: .Migrate) as? Bool ?? false)
// check local user pass to see if user exists
do {
if try isLocalPasswordValid(userName: userToCheck, userPass: passToCheck) {
os_log("Network creds match local creds, nothing to migrate or update.", log: uiLog, type: .default)
if migrate {
os_log("Migrate set, adding migration name hint.", log: uiLog, type: .default)
// set the migration hint
setHint(type: .migrateUser, hint: userToCheck)
return .userMatchSkipMigration
} else {
return .complete
}
} else {
os_log("Local name matches, but not password", log: uiLog, type: .default)
if (getManagedPreference(key: .PasswordOverwriteSilent) as? Bool ?? false) {
// set the hint and return complete
os_log("Setting password to be overwritten.", log: uiLog, type: .default)
setHint(type: .passwordOverride, hint: "true")
return .complete
} else {
return .syncPassword
}
}
} catch DSQueryableErrors.notLocalUser {
os_log("User is not a local user", log: uiLog, type: .default)
if migrate {
getMigrationCandidates()
if migrationUsers?.count ?? 0 < 1 {
os_log("No possible migration candidates, skipping migration", log: uiLog, type: .default)
return .skipMigration
} else {
return .fullMigration
}
} else {
return .complete
}
} catch {
os_log("Unknown migration check error", log: uiLog, type: .default)
return .errorSkipMigration
}
}
fileprivate func getMigrationCandidates() {
do {
if let hiddenMigrationUsers = getManagedPreference(key: .MigrateUsersHide) as? [String] {
migrationUsers = try findNoMADMigrationCandidates(excludeList: hiddenMigrationUsers)
} else {
os_log("No users are hidden from migration.", log: uiLog, type: .default)
migrationUsers = try findNoMADMigrationCandidates()
}
} catch NoMADQueryErrors.noMigrationCandidates {
os_log("No local users to possibly migrate.", log: uiLog, type: .default)
} catch {
let errorText = error.localizedDescription
os_log("Error while determining migration candidate users: %{public}@", log: uiLog, type: .error, errorText)
}
}
func syncPass(oldPass: String) -> Bool {
var userRecord: ODRecord?
do {
userRecord = try getLocalRecord(user)
try userRecord?.changePassword(oldPass, toPassword: pass)
} catch {
if userRecord == nil {
os_log("Unable to obtain local user record.", log: uiLog, type: .default)
} else {
os_log("Unable to change local user password.", log: uiLog, type: .default)
}
return false
}
os_log("Local password changed.", log: uiLog, type: .default)
setHint(type: .migratePass, hint: oldPass)
return true
}
}
...@@ -26,6 +26,8 @@ struct PluginRecord { ...@@ -26,6 +26,8 @@ struct PluginRecord {
typedef struct PluginRecord PluginRecord; typedef struct PluginRecord PluginRecord;
extern OSStatus SecKeychainChangePassword(SecKeychainRef keychainRef, UInt32 oldPasswordLength, const void* oldPassword, UInt32 newPasswordLength, const void* newPassword);
#pragma mark - Mechanism #pragma mark - Mechanism
enum { enum {
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
import Foundation import Foundation
enum Preferences: String { enum Preferences: String, CaseIterable {
/// The desired AD domain as a `String`. /// The desired AD domain as a `String`.
case ADDomain case ADDomain
/// Allows appending of other domains at the loginwindow. Set as a `Bool` to allow any, or as an Array of Strings to whitelist /// Allows appending of other domains at the loginwindow. Set as a `Bool` to allow any, or as an Array of Strings to whitelist
...@@ -25,6 +25,8 @@ enum Preferences: String { ...@@ -25,6 +25,8 @@ enum Preferences: String {
case CreateAdminIfGroupMember case CreateAdminIfGroupMember
/// Should existing mobile accounts be converted into plain local accounts? Set as a Bool`. /// Should existing mobile accounts be converted into plain local accounts? Set as a Bool`.
case DemobilizeUsers case DemobilizeUsers
/// should we check for a password in the hints before demobilzing the user?
case DemobilizeForcePasswordCheck
/// Dissallow local auth, and always do network authentication /// Dissallow local auth, and always do network authentication
case DenyLocal case DenyLocal
/// Users to allow locally when DenyLocal is on /// Users to allow locally when DenyLocal is on
...@@ -47,6 +49,8 @@ enum Preferences: String { ...@@ -47,6 +49,8 @@ enum Preferences: String {
case EULATitle case EULATitle
/// Subhead for EULA as a `String`. /// Subhead for EULA as a `String`.
case EULASubTitle case EULASubTitle
case HideRestart
case HideShutdown
/// Ignore sites in AD. This is a compatibility measure for AD installs that have issues with sites. Set as a `Bool`. /// Ignore sites in AD. This is a compatibility measure for AD installs that have issues with sites. Set as a `Bool`.
case IgnoreSites case IgnoreSites
/// Adds a NoMAD entry into the keychain. `Bool` value. /// Adds a NoMAD entry into the keychain. `Bool` value.
...@@ -69,12 +73,18 @@ enum Preferences: String { ...@@ -69,12 +73,18 @@ enum Preferences: String {
case LoginLogoData case LoginLogoData
/// Should NoLo display a macOS-style login screen instead of a window? Set as a `Bool`, /// Should NoLo display a macOS-style login screen instead of a window? Set as a `Bool`,
case LoginScreen case LoginScreen
/// should we migrate users?
case Migrate
/// should we hide users when we migrate?
case MigrateUsersHide
/// If Notify should add additional logging /// If Notify should add additional logging
case NotifyLogStyle case NotifyLogStyle
/// Path to script to run, currently only one script path can be used, if you want to run this multiple times, keep the logic in your script /// Path to script to run, currently only one script path can be used, if you want to run this multiple times, keep the logic in your script
case ScriptPath case ScriptPath
/// Arguments for the script, if any /// Arguments for the script, if any
case ScriptArgs case ScriptArgs
/// what level the sign in window should be at
case SignInWindowLevel
/// Use the CN from AD as the full name /// Use the CN from AD as the full name
case UseCNForFullName case UseCNForFullName
/// A string to show as the placeholder in the Username textfield /// A string to show as the placeholder in the Username textfield
...@@ -82,6 +92,10 @@ enum Preferences: String { ...@@ -82,6 +92,10 @@ enum Preferences: String {
/// A filesystem path to an image to set the user profile image to as a `String` /// A filesystem path to an image to set the user profile image to as a `String`
case UserProfileImage case UserProfileImage
//Messages
case MessagePasswordSync // what to show when the password needs to sync
//UserInput bits //UserInput bits
case UserInputOutputPath case UserInputOutputPath
...@@ -89,6 +103,50 @@ enum Preferences: String { ...@@ -89,6 +103,50 @@ enum Preferences: String {
case UserInputLogo case UserInputLogo
case UserInputTitle case UserInputTitle
case UserInputMainText case UserInputMainText
//Password update keys
case PasswordOverwriteSilent // will silently update user password to new one
case PasswordOverwriteOptional // allow the user to stomp on the password if interested
}
func printAllPrefs(writeOut: Bool=false) {
var result = ""
for key in Preferences.allCases {
let defaults = UserDefaults.init(suiteName: "menu.nomad.login.ad")
let pref = defaults?.object(forKey: key.rawValue) as AnyObject
switch String(describing: type(of: pref)) {
case "__NSCFBoolean" :
result.append("\t" + key.rawValue + ": " + String(describing: ( defaults?.bool(forKey: key.rawValue))))
case "__NSCFArray" :
result.append("\t" + key.rawValue + ": " + ( String(describing: (defaults?.array(forKey: key.rawValue)!))))
case "__NSTaggedDate", "__NSDate" :
result.append("\t" + key.rawValue + ": " + ( defaults?.object(forKey: key.rawValue) as! Date ).description(with: Locale.current))
case "__NSCFDictionary":
result.append("\t" + key.rawValue + ": " + String(describing: defaults?.dictionary(forKey: key.rawValue)!))
case "__NSCFData" :
result.append("\t" + key.rawValue + ": " + (defaults?.data(forKey: key.rawValue)?.base64EncodedString() ?? "ERROR"))
case "__NSCFNumber" :
result.append("\t" + key.rawValue + ": " + String(describing: defaults?.integer(forKey: key.rawValue)))
default :
result.append("\t" + key.rawValue + ": " + ( defaults?.object(forKey: key.rawValue) as? String ?? "Unset"))
}
if defaults?.objectIsForced(forKey: key.rawValue) ?? false {
result.append("\t\tForced")
}
result.append("\n")
}
if writeOut {
try? result.write(toFile: "/tmp/menu.nomad.login.ad.plist", atomically: true, encoding: String.Encoding.utf8)
} else {
print(result)
}
} }
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
"Mac" : [ "Mac" : [
{ {
"name" : "NoMAD_ADAuth", "name" : "NoMAD_ADAuth",
"hash" : "d15a5ad01c1b4f6a6fcdbeccef7a3661649a3c6b7a5c65d690dd42812b9467bb" "hash" : "f0478d781ee929666841f0b7662efc560e36612a380d67c61ada17c3a43fb146"
} }
], ],
"watchOS" : [ "watchOS" : [
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
<plist version="1.0"> <plist version="1.0">
<dict> <dict>
<key>BuildMachineOSBuild</key> <key>BuildMachineOSBuild</key>
<string>18D42</string> <string>18C54</string>
<key>CFBundleDevelopmentRegion</key> <key>CFBundleDevelopmentRegion</key>
<string>en</string> <string>en</string>
<key>CFBundleExecutable</key> <key>CFBundleExecutable</key>
......
...@@ -12,7 +12,7 @@ import NoMAD_ADAuth ...@@ -12,7 +12,7 @@ import NoMAD_ADAuth
/// Mechanism to create a local user and homefolder. /// Mechanism to create a local user and homefolder.
class CreateUser: NoLoMechanism { class CreateUser: NoLoMechanism, DSQueryable {
//MARK: - Properties //MARK: - Properties
let session = ODSession.default() let session = ODSession.default()
...@@ -87,6 +87,18 @@ class CreateUser: NoLoMechanism { ...@@ -87,6 +87,18 @@ class CreateUser: NoLoMechanism {
// no user to create // no user to create
os_log("Skipping local account creation", log: createUserLog, type: .default) os_log("Skipping local account creation", log: createUserLog, type: .default)
// check to see if we need to overwrite the password
if (getHint(type: .passwordOverride) as? String == "true") {
os_log("Attempting to override user password.", log: createUserLog)
do {
let localUserRecord = try getLocalRecord(nomadUser ?? "NONE")
try localUserRecord.changePassword(nil, toPassword: nomadPass)
} catch {
os_log("Unable to override user password", log: createUserLog)
}
}
// Set the login timestamp if requested // Set the login timestamp if requested
setTimestampFor(nomadUser as? String ?? "") setTimestampFor(nomadUser as? String ?? "")
...@@ -339,6 +351,8 @@ class CreateUser: NoLoMechanism { ...@@ -339,6 +351,8 @@ class CreateUser: NoLoMechanism {
return "English" + templateName return "English" + templateName
case "fr": case "fr":
return "French" + templateName return "French" + templateName
case "de":
return "German" + templateName
case "it": case "it":
return "Italian" + templateName return "Italian" + templateName
case "ja": case "ja":
......
...@@ -61,14 +61,16 @@ class DeMobilize : NoLoMechanism { ...@@ -61,14 +61,16 @@ class DeMobilize : NoLoMechanism {
return return
} }
// sanity check to ensure we have valid information and a local user if (getManagedPreference(key: Preferences.DemobilizeForcePasswordCheck) as? Bool ?? false) {
os_log("Checking for password", log: demobilizeLog, type: .debug) // sanity check to ensure we have valid information and a local user
if passwordContext == nil { os_log("Checking for password", log: demobilizeLog, type: .debug)
os_log("Something went wrong, there is no password in user data", log: demobilizeLog, type: .error) if passwordContext == nil {
// nothing to see here, most likely auth failed earlier on os_log("Something went wrong, there is no password in user data", log: demobilizeLog, type: .error)
// we're just here for auditing purposes // nothing to see here, most likely auth failed earlier on
_ = allowLogin() // we're just here for auditing purposes
return _ = allowLogin()
return
}
} }
// get local user record // get local user record
......
...@@ -87,7 +87,26 @@ class KeychainAdd : NoLoMechanism { ...@@ -87,7 +87,26 @@ class KeychainAdd : NoLoMechanism {
os_log("Unable to unlock keychain reference.", log: keychainAddLog, type: .default) os_log("Unable to unlock keychain reference.", log: keychainAddLog, type: .default)
// check if we should reset // check if we should reset
if getManagedPreference(key: .KeychainReset) as? Bool == true {
if let resetPass = getHint(type: .migratePass) as? String {
os_log("Resetting keychain with migrated user/pass.", log: keychainAddLog)
var myKeychain : SecKeychain?
err = SecKeychainOpen(userKeychainPath, &myKeychain)
err = SecKeychainChangePassword(myKeychain, UInt32(resetPass.count), resetPass, UInt32(userpass.count), userpass)
if err != 0 {
os_log("Unable to reset keychain with migrated user/pass.", log: keychainAddLog, type: .error)
if (getManagedPreference(key: .KeychainReset) as? Bool ?? true ) {
os_log("Resetting keychain password.", log: keychainAddLog, type: .info)
clearKeychain(path: homeDir)
}
}
} else if (getManagedPreference(key: .KeychainReset) as? Bool ?? true ) {
os_log("Resetting keychain password.", log: keychainAddLog, type: .info) os_log("Resetting keychain password.", log: keychainAddLog, type: .info)
clearKeychain(path: homeDir) clearKeychain(path: homeDir)
} else { } else {
......
...@@ -74,6 +74,10 @@ class LogOnly : NoLoMechanism { ...@@ -74,6 +74,10 @@ class LogOnly : NoLoMechanism {
os_log("Hint item %{public}@: %{public}@", log: loggerMech, type: .default, item, result) os_log("Hint item %{public}@: %{public}@", log: loggerMech, type: .default, item, result)
} }
} }
os_log("Printing all preferences", log: loggerMech, type: .debug)
let _ = allowLogin() let _ = allowLogin()
os_log("LogOnly mech complete", log: loggerMech, type: .debug) os_log("LogOnly mech complete", log: loggerMech, type: .debug)
......
...@@ -15,6 +15,13 @@ class Notify : NoLoMechanism { ...@@ -15,6 +15,13 @@ class Notify : NoLoMechanism {
@objc func run() { @objc func run() {
// check if we should skip this or not
if FileManager.default.fileExists(atPath: "/tmp/.skipNotify") {
_ = allowLogin()
return
}
NSApp.activate(ignoringOtherApps: true) NSApp.activate(ignoringOtherApps: true)
let notifyWindow = NoLoNotify(windowNibName: NSNib.Name("NoLoNotify")) let notifyWindow = NoLoNotify(windowNibName: NSNib.Name("NoLoNotify"))
......
...@@ -12,6 +12,14 @@ import Cocoa ...@@ -12,6 +12,14 @@ import Cocoa
@objc class UserInput : NoLoMechanism { @objc class UserInput : NoLoMechanism {
@objc func run() { @objc func run() {
// check if we should skip this or not
if FileManager.default.fileExists(atPath: "/tmp/.skipUserInput") {
_ = allowLogin()
return
}
// run the UI if we have the settings // run the UI if we have the settings
if let inputSettings = getManagedPreference(key: .UserInputUI) as? [ String : AnyObject ] { if let inputSettings = getManagedPreference(key: .UserInputUI) as? [ String : AnyObject ] {
......
...@@ -7,9 +7,11 @@ ...@@ -7,9 +7,11 @@
objects = { objects = {
/* Begin PBXBuildFile section */ /* Begin PBXBuildFile section */
0126150B2200E2F00058E5CA /* NoMAD_ADAuth.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9C7FA0B6203369DA00E7D67B /* NoMAD_ADAuth.framework */; };
0126150C2200E3000058E5CA /* NoMAD_ADAuth.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 9C7FA0B6203369DA00E7D67B /* NoMAD_ADAuth.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 0126150C2200E3000058E5CA /* NoMAD_ADAuth.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 9C7FA0B6203369DA00E7D67B /* NoMAD_ADAuth.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
017F5D1722022A0700042737 /* NoMAD_ADAuth.framework.dSYM in CopyFiles */ = {isa = PBXBuildFile; fileRef = 017F5D1622022A0700042737 /* NoMAD_ADAuth.framework.dSYM */; }; 017F5D1722022A0700042737 /* NoMAD_ADAuth.framework.dSYM in CopyFiles */ = {isa = PBXBuildFile; fileRef = 017F5D1622022A0700042737 /* NoMAD_ADAuth.framework.dSYM */; };
1A43759E221CF00E00D1B976 /* LocalCheckAndMigrate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A43759D221CF00E00D1B976 /* LocalCheckAndMigrate.swift */; };
1A4375A0221CF08400D1B976 /* DSQueryable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A43759F221CF08400D1B976 /* DSQueryable.swift */; };
1A4375A2221CF13500D1B976 /* DS+NoMAD.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A4375A1221CF13500D1B976 /* DS+NoMAD.swift */; };
1AA58EF9216610B300431201 /* UserInput.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1AA58EF8216610B300431201 /* UserInput.swift */; }; 1AA58EF9216610B300431201 /* UserInput.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1AA58EF8216610B300431201 /* UserInput.swift */; };
1AA58EFB216610C300431201 /* Notify.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1AA58EFA216610C300431201 /* Notify.swift */; }; 1AA58EFB216610C300431201 /* Notify.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1AA58EFA216610C300431201 /* Notify.swift */; };
1AA58EFD216610C700431201 /* RunScript.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1AA58EFC216610C700431201 /* RunScript.swift */; }; 1AA58EFD216610C700431201 /* RunScript.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1AA58EFC216610C700431201 /* RunScript.swift */; };
...@@ -21,6 +23,7 @@ ...@@ -21,6 +23,7 @@
1AA58F03216611C100431201 /* UserInputUI.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1AA58EEA2166101100431201 /* UserInputUI.swift */; }; 1AA58F03216611C100431201 /* UserInputUI.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1AA58EEA2166101100431201 /* UserInputUI.swift */; };
1AA58F04216611C400431201 /* UserInputUI.xib in Resources */ = {isa = PBXBuildFile; fileRef = 1AA58EEB2166101100431201 /* UserInputUI.xib */; }; 1AA58F04216611C400431201 /* UserInputUI.xib in Resources */ = {isa = PBXBuildFile; fileRef = 1AA58EEB2166101100431201 /* UserInputUI.xib */; };
1AACDAE02217B72B006D8A65 /* NoLoUserInput Sample.mobileconfig in Resources */ = {isa = PBXBuildFile; fileRef = 1AACDADF2217B72A006D8A65 /* NoLoUserInput Sample.mobileconfig */; }; 1AACDAE02217B72B006D8A65 /* NoLoUserInput Sample.mobileconfig in Resources */ = {isa = PBXBuildFile; fileRef = 1AACDADF2217B72A006D8A65 /* NoLoUserInput Sample.mobileconfig */; };
1AACDAE12217BAFC006D8A65 /* NoMAD_ADAuth.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9C7FA0B6203369DA00E7D67B /* NoMAD_ADAuth.framework */; };
1AF15E8721B1F85E00D36F3E /* NoLoWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1AF15E8621B1F85E00D36F3E /* NoLoWindow.swift */; }; 1AF15E8721B1F85E00D36F3E /* NoLoWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1AF15E8621B1F85E00D36F3E /* NoLoWindow.swift */; };
9C0A3EA41FF2CCD70030A04F /* LoggingDefinitions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9C0A3EA31FF2CCD70030A04F /* LoggingDefinitions.swift */; }; 9C0A3EA41FF2CCD70030A04F /* LoggingDefinitions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9C0A3EA31FF2CCD70030A04F /* LoggingDefinitions.swift */; };
9C468F812006A95400A475FC /* Preferences.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9C468F802006A95400A475FC /* Preferences.swift */; }; 9C468F812006A95400A475FC /* Preferences.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9C468F802006A95400A475FC /* Preferences.swift */; };
...@@ -67,6 +70,9 @@ ...@@ -67,6 +70,9 @@
/* Begin PBXFileReference section */ /* Begin PBXFileReference section */
017F5D1622022A0700042737 /* NoMAD_ADAuth.framework.dSYM */ = {isa = PBXFileReference; lastKnownFileType = wrapper.dsym; path = NoMAD_ADAuth.framework.dSYM; sourceTree = "<group>"; }; 017F5D1622022A0700042737 /* NoMAD_ADAuth.framework.dSYM */ = {isa = PBXFileReference; lastKnownFileType = wrapper.dsym; path = NoMAD_ADAuth.framework.dSYM; sourceTree = "<group>"; };
1A43759D221CF00E00D1B976 /* LocalCheckAndMigrate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocalCheckAndMigrate.swift; sourceTree = "<group>"; };
1A43759F221CF08400D1B976 /* DSQueryable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DSQueryable.swift; sourceTree = "<group>"; };
1A4375A1221CF13500D1B976 /* DS+NoMAD.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "DS+NoMAD.swift"; sourceTree = "<group>"; };
1AA58EEA2166101100431201 /* UserInputUI.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserInputUI.swift; sourceTree = "<group>"; }; 1AA58EEA2166101100431201 /* UserInputUI.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserInputUI.swift; sourceTree = "<group>"; };
1AA58EEB2166101100431201 /* UserInputUI.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = UserInputUI.xib; sourceTree = "<group>"; }; 1AA58EEB2166101100431201 /* UserInputUI.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = UserInputUI.xib; sourceTree = "<group>"; };
1AA58EED2166104400431201 /* NoLoNotify.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = NoLoNotify.xib; sourceTree = "<group>"; }; 1AA58EED2166104400431201 /* NoLoNotify.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = NoLoNotify.xib; sourceTree = "<group>"; };
...@@ -114,7 +120,7 @@ ...@@ -114,7 +120,7 @@
isa = PBXFrameworksBuildPhase; isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
0126150B2200E2F00058E5CA /* NoMAD_ADAuth.framework in Frameworks */, 1AACDAE12217BAFC006D8A65 /* NoMAD_ADAuth.framework in Frameworks */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };
...@@ -235,9 +241,12 @@ ...@@ -235,9 +241,12 @@
9CBDCFB61FC5CE2900CF73F4 /* Base */ = { 9CBDCFB61FC5CE2900CF73F4 /* Base */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
1A43759F221CF08400D1B976 /* DSQueryable.swift */,
1A43759D221CF00E00D1B976 /* LocalCheckAndMigrate.swift */,
9CBDCFA71FC5CDB500CF73F4 /* NoMADLoginAD-Bridging-Header.h */, 9CBDCFA71FC5CDB500CF73F4 /* NoMADLoginAD-Bridging-Header.h */,
9CBDCFB41FC5CE2100CF73F4 /* NoMADLoginAD.h */, 9CBDCFB41FC5CE2100CF73F4 /* NoMADLoginAD.h */,
9CBDCFB31FC5CE2100CF73F4 /* NoMADLoginAD.m */, 9CBDCFB31FC5CE2100CF73F4 /* NoMADLoginAD.m */,
1A4375A1221CF13500D1B976 /* DS+NoMAD.swift */,
9C6027451FE8224000B99B51 /* ContextAndHintHandling.swift */, 9C6027451FE8224000B99B51 /* ContextAndHintHandling.swift */,
9C8A2608207D917900204336 /* DataExtension.swift */, 9C8A2608207D917900204336 /* DataExtension.swift */,
9C0A3EA31FF2CCD70030A04F /* LoggingDefinitions.swift */, 9C0A3EA31FF2CCD70030A04F /* LoggingDefinitions.swift */,
...@@ -343,10 +352,13 @@ ...@@ -343,10 +352,13 @@
9CA733FC202E491E00EA1FE6 /* PowerControl.swift in Sources */, 9CA733FC202E491E00EA1FE6 /* PowerControl.swift in Sources */,
1AA58F01216611BA00431201 /* EULAUI.swift in Sources */, 1AA58F01216611BA00431201 /* EULAUI.swift in Sources */,
1AA58EFF216611B400431201 /* Tracker.swift in Sources */, 1AA58EFF216611B400431201 /* Tracker.swift in Sources */,
1A43759E221CF00E00D1B976 /* LocalCheckAndMigrate.swift in Sources */,
1AA58F03216611C100431201 /* UserInputUI.swift in Sources */, 1AA58F03216611C100431201 /* UserInputUI.swift in Sources */,
9C8A2609207D917900204336 /* DataExtension.swift in Sources */, 9C8A2609207D917900204336 /* DataExtension.swift in Sources */,
9CBDCFAF1FC5CDB600CF73F4 /* NoLoMechanism.swift in Sources */, 9CBDCFAF1FC5CDB600CF73F4 /* NoLoMechanism.swift in Sources */,
1A4375A2221CF13500D1B976 /* DS+NoMAD.swift in Sources */,
9CC74CC91FFED59B00EBCCD5 /* DeMobilize.swift in Sources */, 9CC74CC91FFED59B00EBCCD5 /* DeMobilize.swift in Sources */,
1A4375A0221CF08400D1B976 /* DSQueryable.swift in Sources */,
1AA58EF9216610B300431201 /* UserInput.swift in Sources */, 1AA58EF9216610B300431201 /* UserInput.swift in Sources */,
9CBDCFAD1FC5CDB600CF73F4 /* CreateUser.swift in Sources */, 9CBDCFAD1FC5CDB600CF73F4 /* CreateUser.swift in Sources */,
9CBDCFBA1FC5CE6100CF73F4 /* SignIn.swift in Sources */, 9CBDCFBA1FC5CE6100CF73F4 /* SignIn.swift in Sources */,
......
...@@ -15,9 +15,9 @@ ...@@ -15,9 +15,9 @@
<key>CFBundlePackageType</key> <key>CFBundlePackageType</key>
<string>BNDL</string> <string>BNDL</string>
<key>CFBundleShortVersionString</key> <key>CFBundleShortVersionString</key>
<string>1.3.0</string> <string>1.4.0-Alpha5</string>
<key>CFBundleVersion</key> <key>CFBundleVersion</key>
<string>329</string> <string>337</string>
<key>NSHumanReadableCopyright</key> <key>NSHumanReadableCopyright</key>
<string>Copyright © 2019 Orchard &amp; Grove. All rights reserved.</string> <string>Copyright © 2019 Orchard &amp; Grove. All rights reserved.</string>
<key>NSPrincipalClass</key> <key>NSPrincipalClass</key>
......
This diff is collapsed.
This diff is collapsed.