ruby-jss 2.1.0b5 → 2.1.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3e4edfd42bf486020f780c565948d0b6de6db11413eaaf2f5a486243d8137a76
4
- data.tar.gz: 0c3b1e370c9f1ffdcf97f7174b0dbc508f3c414efc5a86a0b5b09e0c42ba4e3f
3
+ metadata.gz: efe85ea732df2a1ce119273c532084459fdb9ebe6316d62ab7afa533d9c4adc8
4
+ data.tar.gz: e42de1baecb51f2886d704e63818d24063d4332a0b17170c2977aa3e336656a5
5
5
  SHA512:
6
- metadata.gz: 7fd967954cc7642ec10054fff0c2d75f3dd30bce1836baf158a1fb4abe4f5d8a95ca493e9c1ef2b03fe1490874fdbf3f42b81af46389c7a86a6a73bdaeb867c2
7
- data.tar.gz: f806304ae8b9fad9fae2ffc35b77681a26cf2bfd63dc202b5a52f25b43e2e278fda62321f05e0c3f47a6e063238b5eda86ec870814a971fb13e7631ecfa04f5a
6
+ metadata.gz: 6a0874d08b6c7fc3aa93c207c81ab3a09c0b822e5f035ddb5192144d04fbe3a846db6c6528a8150cd81a2ee9f994155d4b7ba396d11ef7ecf565c9330b99aae6
7
+ data.tar.gz: fb3bdf758de69f290974def92a42ff279f1c98611373116304fbe618b0536f59361d892c3444db88c952c2208bb7cfbf0763cba8a959bd84cffb3ca5f8bee8e7
data/CHANGES.md CHANGED
@@ -14,7 +14,19 @@ __Please update all installations of ruby-jss to at least v1.6.0.__
14
14
 
15
15
  Many many thanks to actae0n of Blacksun Hackers Club for reporting this issue and providing examples of how it could be exploited.
16
16
 
17
- ## \[2.1.0] - unreleased
17
+ --------
18
+
19
+ ## \[2.1.1] - 2022-11-07
20
+
21
+ ### Fixed & Deprecated
22
+
23
+ - The classic API no longer includes SHA256 hashes of various passwords - the data value is there, but only contains a string of asterisks. As such, ruby-jss can no longer use those to validate some passwords before trying to use them. The methods doing so are still present, but only return `true`. If an incorrect password is given, the underlying process that uses it will fail on its own.
24
+ These methods will be removed in a future version of ruby-jss:
25
+ - `Jamf::DistributionPoint#check_pw` Used mostly by the `Jamf::DistributionPoint#mount` method
26
+ - `Jamf::Policy.verify_management_password`
27
+
28
+
29
+ ## \[2.1.0] - 2022-10-10
18
30
 
19
31
  ### Added
20
32
 
@@ -34,6 +46,8 @@ Many many thanks to actae0n of Blacksun Hackers Club for reporting this issue an
34
46
  - A few internal rescues of a deprecated exception class
35
47
  - Removed auto-loading of deprecation files; now explicitly loaded.
36
48
  - A few Ruby 2 => Ruby 3 bugs - method params needing double-splats (Thanks to @Timelost for reporting this one)
49
+ - Ensure resource paths don't start with a slash
50
+ - Setting the timeouts on an existing API connection object now works.
37
51
 
38
52
  ## \[2.0.0] - 2022-09-12
39
53
 
data/bin/cgrouper CHANGED
@@ -55,7 +55,7 @@ class App
55
55
  ###
56
56
  ### set up
57
57
  ###
58
- def initialize(**_args)
58
+ def initialize
59
59
  @debug = false
60
60
 
61
61
  # define the options
@@ -207,7 +207,7 @@ class App
207
207
 
208
208
  # smart groups can't have some things done to them
209
209
  if ACTIONS_FOR_STATIC_GROUPS_ONLY.include? @options.action and @group.smart?
210
- raise InvalidTypeError,
210
+ raise InvalidTypeError,
211
211
  "You can't do that to a smart group. Use the JSS WebApp if needed."
212
212
  end
213
213
 
@@ -384,7 +384,6 @@ Notes:
384
384
  return unless @options.action == :create_group or confirm "add computers to group '#{@group.name}'"
385
385
 
386
386
  @options.computers.each do |c|
387
-
388
387
  @group.add_member c
389
388
  rescue JSS::NoSuchItemError
390
389
  puts "#{$!} - skipping"
@@ -404,11 +403,9 @@ Notes:
404
403
  return unless confirm "remove computers from group '#{@group.name}'"
405
404
 
406
405
  @options.computers.each do |c|
407
-
408
406
  @group.remove_member c
409
407
  rescue JSS::NoSuchItemError
410
408
  puts "#{$!} - skipping"
411
-
412
409
  end
413
410
  @group.update
414
411
  end
@@ -459,7 +456,7 @@ end # class App
459
456
 
460
457
  #######################################
461
458
  begin
462
- app = App.new(ARGV)
459
+ app = App.new
463
460
  app.run
464
461
  rescue
465
462
  # handle exceptions not handled elsewhere
data/bin/netseg-update CHANGED
@@ -55,13 +55,13 @@ class App
55
55
 
56
56
  USAGE = "Usage: #{PROG_NAME} [options] [--help] /path/to/file".freeze
57
57
 
58
- POTENTIAL_COLUMNS = %i(name starting ending cidr mask).freeze
58
+ POTENTIAL_COLUMNS = %i[name starting ending cidr mask].freeze
59
59
 
60
60
  DEFAULT_CACHE_FILE = Pathname.new('~/.last_subnet_update').expand_path
61
61
 
62
62
  DEFAULT_DELIMITER = "\t".freeze
63
63
 
64
- DEFAULT_COLUMNS = [:name, :starting, :ending].freeze
64
+ DEFAULT_COLUMNS = %i[name starting ending].freeze
65
65
 
66
66
  DEFAULT_MANUAL_PREFIX = 'Manual-'.freeze
67
67
 
@@ -84,7 +84,7 @@ class App
84
84
 
85
85
  attr_reader :debug
86
86
 
87
- def initialize(_args)
87
+ def initialize
88
88
  @getpass = $stdin.tty? ? :prompt : :stdin
89
89
  set_defaults
90
90
  parse_cli
@@ -183,7 +183,7 @@ Options:
183
183
  -V, --no-verify-cert - Allow self-signed, unverified SSL certificate
184
184
  -T, --timeout secs - specify the JSS API timeout
185
185
  -N, --no-op - Don't make any changes in the JSS, just report what would
186
- have be changed.
186
+ have been changed.
187
187
  -H, --help - show this help
188
188
  --debug - show the ruby backtrace when errors occur
189
189
 
@@ -254,6 +254,7 @@ Notes:
254
254
  lines.each do |line|
255
255
  parsed_line = parse_a_data_line line
256
256
  next unless parsed_line
257
+
257
258
  name = parsed_line.delete :name
258
259
  parsed_data[name] = parsed_line
259
260
  end
@@ -273,6 +274,7 @@ Notes:
273
274
  @columns.include?(:ending) || \
274
275
  @columns.include?(:cidr) || \
275
276
  @columns.include?(:mask)
277
+
276
278
  @use_cidr = (@columns.include?(:cidr) || @columns.include?(:mask))
277
279
  end
278
280
 
@@ -296,11 +298,13 @@ Notes:
296
298
  # read in the file
297
299
  @raw_data = @file.read
298
300
  return true unless @cache_file.exist?
301
+
299
302
  @raw_data != @cache_file.read
300
303
  end
301
304
 
302
305
  def cache_latest_data
303
306
  return if @noop
307
+
304
308
  @cache_file.jss_save @raw_data
305
309
  end
306
310
 
@@ -375,7 +379,7 @@ end # app
375
379
  # create the app and go
376
380
  begin
377
381
  debug = ARGV.include? '--debug'
378
- app = App.new(ARGV)
382
+ app = App.new
379
383
  app.run
380
384
  rescue
381
385
  # handle exceptions not handled elsewhere
@@ -440,7 +440,7 @@ module Jamf
440
440
  cnx = api if api
441
441
 
442
442
  id = valid_id ident, cnx: cnx
443
- raise "No computer matches identifier: #{ident}" unless id
443
+ raise Jamf::NoSuchItemError, "No computer matches identifier: #{ident}" unless id
444
444
 
445
445
  end_date ||= start_date
446
446
  start_date = Jamf.parse_time start_date
@@ -259,8 +259,8 @@ module Jamf
259
259
  attr_reader :ssh_password_sha256
260
260
 
261
261
  def initialize(**args)
262
- super
263
-
262
+ super
263
+
264
264
  @ip_address = @init_data[:ip_address]
265
265
  @local_path = @init_data[:local_path]
266
266
  @enable_load_balancing = @init_data[:enable_load_balancing]
@@ -294,44 +294,28 @@ module Jamf
294
294
 
295
295
  @port = @init_data[:ssh_password]
296
296
 
297
- # Note, as of Casper 9.3:
298
- # :management_password_md5=>"xxxxx"
299
- # and
300
- # :management_password_sha256=> "xxxxxxxxxx"
301
- # Are the read/write password
302
- #
303
- # An empty passwd is
304
- # MD5 = d41d8cd98f00b204e9800998ecf8427e
305
- # SHA256 = e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
306
- #
307
- # Seemms the read-only pw isn't available in the API
308
-
309
297
  # if we mount for fileservice, where's the mountpoint?
310
298
  @mountpoint = DEFAULT_MOUNTPOINT_DIR + "#{DEFAULT_MOUNTPOINT_PREFIX}#{@id}"
311
299
  end # init
312
300
 
313
- # Check the validity of a password.
301
+ # @deprecated The API no longer sends SHA256 hashed password data, and instead
302
+ # only has a string of asterisks, meaning we can no longer use it to validate
303
+ # passwords before attempting to use them. Instead, the processes that use
304
+ # them, e.g. mounting a Dist. Point, will fail on their own if the pw is not
305
+ # valid.
314
306
  #
315
- # @param user[Symbol] one of :ro, :rw, :ssh, :http
307
+ # This method remains defined for backward-compatibility with any existing
308
+ # code that calls it. but it will always return true. It will be removed in
309
+ # a future version
316
310
  #
317
- # @param pw[String] the password to check for the given user
311
+ # @param user[Symbol] ignored
318
312
  #
319
- # @return [Boolean,Nil] was the password correct?
320
- # nil is returned if there is no password set in the JSS.
313
+ # @param pw[String] ignored
321
314
  #
322
- def check_pw(user, pw)
323
- raise Jamf::InvalidDataError, 'The first parameter must be one of :ro, :rw, :ssh, :http' unless %i[ro rw ssh http].include? user
324
-
325
- sha256 = case user
326
- when :rw then @read_write_password_sha256
327
- when :ro then @read_only_password_sha256
328
- when :http then @http_password_sha256
329
- when :ssh then @ssh_password_sha256
330
- end # case
331
-
332
- return nil if sha256 == EMPTY_PW_256
333
-
334
- sha256 == Digest::SHA2.new(256).update(pw).to_s
315
+ # @return [TrueClass] Allow the process calling this to continue.
316
+ #
317
+ def check_pw(_user = nil, _pw = nil)
318
+ true
335
319
  end
336
320
 
337
321
  # Check to see if this dist point is reachable for downloads (read-only)
@@ -350,7 +334,6 @@ module Jamf
350
334
  def reachable_for_download?(pw = '', check_http = true)
351
335
  return :http if check_http && http_reachable?(pw)
352
336
  return :mountable if mounted?
353
- return false unless check_pw :ro, pw
354
337
 
355
338
  begin
356
339
  mount pw, :ro
@@ -371,7 +354,6 @@ module Jamf
371
354
  #
372
355
  def reachable_for_upload?(pw)
373
356
  return :mountable if mounted?
374
- return false unless check_pw :rw, pw
375
357
 
376
358
  begin
377
359
  mount pw, :rw
@@ -413,12 +395,6 @@ module Jamf
413
395
  pw
414
396
  end
415
397
 
416
- pwok = check_pw(access, password)
417
- unless pwok
418
- msg = pwok.nil? ? "No #{access} password set in the JSS" : "Incorrect password for #{access} account"
419
- raise Jamf::InvalidDataError, msg
420
- end
421
-
422
398
  username = access == :ro ? @read_only_username : @read_write_username
423
399
 
424
400
  safe_pw = CGI.escape password.to_s
@@ -481,7 +457,7 @@ module Jamf
481
457
  private
482
458
 
483
459
  # can the dp be reached for http downloads?
484
- def http_reachable?(pw)
460
+ def http_reachable?(pw = nil)
485
461
  return false unless http_downloads_enabled
486
462
 
487
463
  url =
@@ -154,7 +154,7 @@ module Jamf
154
154
  # when fetching a specific version, this is a valid version
155
155
  UNKNOWN_VERSION_ID = 'Unknown'.freeze
156
156
 
157
- REPORTS_RSRC_BASE = '/patchreports/patchsoftwaretitleid'.freeze
157
+ REPORTS_RSRC_BASE = 'patchreports/patchsoftwaretitleid'.freeze
158
158
 
159
159
  # Class Methods
160
160
  #######################################
@@ -233,7 +233,7 @@ module Jamf
233
233
  all(refresh, cnx: cnx).map { |i| i[:source_name_id] }
234
234
  end
235
235
 
236
- # Get a patch report for a softwaretitle, withouth fetching an instance.
236
+ # Get a patch report for a softwaretitle, without fetching an instance.
237
237
  # Defaults to reporting all versions. Specifiying a version will be faster.
238
238
  #
239
239
  # The Hash returned has 3 keys:
@@ -269,6 +269,7 @@ module Jamf
269
269
 
270
270
  # TODO: remove this and adjust parsing when jamf fixes the JSON
271
271
  raw_report = XMLWorkaround.data_via_xml(rsrc, PATCH_REPORT_DATA_MAP, cnx)[:patch_report]
272
+
272
273
  report = {}
273
274
  report[:total_computers] = raw_report[:total_computers]
274
275
  report[:total_versions] = raw_report[:total_versions]
@@ -312,7 +313,7 @@ module Jamf
312
313
  # so all other lookup values have to be converted to ID before
313
314
  # the call to super
314
315
  #
315
- def self.fetch(identifier = nil, **params)
316
+ def self.fetch(identifier = nil, **params)
316
317
  # default connection if unspecified
317
318
  cnx = params.delete :cnx
318
319
  cnx ||= params.delete :api # backward compatibility, deprecated
@@ -472,7 +473,6 @@ module Jamf
472
473
  # wrapper to fetch versions after creating
473
474
  def create
474
475
  super
475
-
476
476
  end
477
477
 
478
478
  # wrapper to clear @changed_pkgs after updating
@@ -166,7 +166,7 @@ module Jamf
166
166
  selected: 'Currently Selected Startup Disk (No Bless)',
167
167
  netboot: 'NetBoot',
168
168
  os_installer: 'inPlaceOSUpgradeDirectory'
169
- }.freeze # Note: any other value in :specify_startup is a path to some other drive to boot from, e.g. /Volumes/Foo
169
+ }.freeze # NOTE: any other value in :specify_startup is a path to some other drive to boot from, e.g. /Volumes/Foo
170
170
 
171
171
  ACCOUNT_ACTIONS = {
172
172
  create: 'Create',
@@ -200,9 +200,9 @@ module Jamf
200
200
  }.freeze
201
201
 
202
202
  DISK_ENCRYPTION_ACTIONS = {
203
- apply: "apply",
204
- remediate: "remediate",
205
- none: "none"
203
+ apply: 'apply',
204
+ remediate: 'remediate',
205
+ none: 'none'
206
206
  }
207
207
 
208
208
  PRINTER_ACTIONS = {
@@ -751,7 +751,7 @@ module Jamf
751
751
  @management_account = amaint[:management_account]
752
752
  @accounts = amaint[:accounts]
753
753
 
754
- @packages = @init_data[:package_configuration][:packages] ? @init_data[:package_configuration][:packages] : []
754
+ @packages = @init_data[:package_configuration][:packages] || []
755
755
 
756
756
  @scripts = @init_data[:scripts]
757
757
 
@@ -815,6 +815,7 @@ module Jamf
815
815
  #
816
816
  def enabled=(new_val)
817
817
  return if @enabled == new_val
818
+
818
819
  @enabled = Jamf::Validate.boolean new_val
819
820
  @need_to_update = true
820
821
  end
@@ -868,9 +869,7 @@ module Jamf
868
869
 
869
870
  # if the event is not 'none' and attempts is <= 0,
870
871
  # set events to 1, or the API won't accept it
871
- unless evt == RETRY_EVENTS[:none]
872
- @retry_attempts = 1 unless @retry_attempts.positive?
873
- end
872
+ @retry_attempts = 1 if !(evt == RETRY_EVENTS[:none]) && !@retry_attempts.positive?
874
873
 
875
874
  @retry_event = evt
876
875
  @need_to_update = true
@@ -934,6 +933,7 @@ module Jamf
934
933
  #
935
934
  def target_drive=(path_to_drive)
936
935
  raise Jamf::InvalidDataError, 'Path to target drive must be absolute' unless path_to_drive.to_s.start_with? '/'
936
+
937
937
  @target_drive = path_to_drive.to_s
938
938
  @need_to_update = true
939
939
  end
@@ -946,6 +946,7 @@ module Jamf
946
946
  #
947
947
  def offline=(new_val)
948
948
  raise Jamf::InvalidDataError, 'New value must be boolean true or false' unless Jamf::TRUE_FALSE.include? new_val
949
+
949
950
  @offline = new_val
950
951
  @need_to_update = true
951
952
  end
@@ -960,6 +961,7 @@ module Jamf
960
961
  #
961
962
  def set_trigger_event(type, new_val)
962
963
  raise Jamf::InvalidDataError, "Trigger type must be one of #{TRIGGER_EVENTS.keys.join(', ')}" unless TRIGGER_EVENTS.key?(type)
964
+
963
965
  if type == :custom
964
966
  raise Jamf::InvalidDataError, 'Custom triggers must be Strings' unless new_val.is_a? String
965
967
  else
@@ -977,6 +979,7 @@ module Jamf
977
979
  #
978
980
  def server_side_activation=(activation)
979
981
  raise Jamf::InvalidDataError, 'Activation must be a Time' unless activation.is_a? Time
982
+
980
983
  @server_side_limitations[:activation] = activation
981
984
  @need_to_update = true
982
985
  end
@@ -989,6 +992,7 @@ module Jamf
989
992
  #
990
993
  def server_side_expiration=(expiration)
991
994
  raise Jamf::InvalidDataError, 'Expiration must be a Time' unless expiration.is_a? Time
995
+
992
996
  @server_side_limitations[:expiration] = expiration
993
997
  @need_to_update = true
994
998
  end
@@ -999,6 +1003,7 @@ module Jamf
999
1003
  #
1000
1004
  def verify_startup_disk=(bool)
1001
1005
  return if @verify_startup_disk == bool
1006
+
1002
1007
  @verify_startup_disk = Jamf::Validate.boolean bool
1003
1008
  @need_to_update = true
1004
1009
  end
@@ -1007,6 +1012,7 @@ module Jamf
1007
1012
  #
1008
1013
  def permissions_repair=(bool)
1009
1014
  return if @permissions_repair == bool
1015
+
1010
1016
  @permissions_repair = Jamf::Validate.boolean bool
1011
1017
  @need_to_update = true
1012
1018
  end
@@ -1015,6 +1021,7 @@ module Jamf
1015
1021
  #
1016
1022
  def recon=(bool)
1017
1023
  return if @recon == bool
1024
+
1018
1025
  @recon = Jamf::Validate.boolean bool
1019
1026
  @need_to_update = true
1020
1027
  end
@@ -1024,6 +1031,7 @@ module Jamf
1024
1031
  #
1025
1032
  def fix_byhost=(bool)
1026
1033
  return if @fix_byhost == bool
1034
+
1027
1035
  @fix_byhost = Jamf::Validate.boolean bool
1028
1036
  @need_to_update = true
1029
1037
  end
@@ -1032,6 +1040,7 @@ module Jamf
1032
1040
  #
1033
1041
  def reset_name=(bool)
1034
1042
  return if @reset_name == bool
1043
+
1035
1044
  @reset_name = Jamf::Validate.boolean bool
1036
1045
  @need_to_update = true
1037
1046
  end
@@ -1040,6 +1049,7 @@ module Jamf
1040
1049
  #
1041
1050
  def flush_system_cache=(bool)
1042
1051
  return if @flush_system_cache == bool
1052
+
1043
1053
  @flush_system_cache = Jamf::Validate.boolean bool
1044
1054
  @need_to_update = true
1045
1055
  end # see attr_reader :recon
@@ -1048,6 +1058,7 @@ module Jamf
1048
1058
  #
1049
1059
  def install_cached_pkgs=(bool)
1050
1060
  return if @install_cached_pkgs == bool
1061
+
1051
1062
  @install_cached_pkgs = Jamf::Validate.boolean bool
1052
1063
  @need_to_update = true
1053
1064
  end
@@ -1056,6 +1067,7 @@ module Jamf
1056
1067
  #
1057
1068
  def flush_user_cache=(bool)
1058
1069
  return if @flush_user_cache == bool
1070
+
1059
1071
  @flush_user_cache = Jamf::Validate.boolean bool
1060
1072
  @need_to_update = true
1061
1073
  end
@@ -1071,6 +1083,7 @@ module Jamf
1071
1083
  #
1072
1084
  def no_user_logged_in=(no_user_option)
1073
1085
  raise Jamf::InvalidDataError, "no_user_logged_in options: #{NO_USER_LOGGED_IN.join(', ')}" unless NO_USER_LOGGED_IN.include? no_user_option
1086
+
1074
1087
  @reboot_options[:no_user_logged_in] = no_user_option
1075
1088
  @need_to_update = true
1076
1089
  end
@@ -1083,6 +1096,7 @@ module Jamf
1083
1096
  #
1084
1097
  def user_logged_in=(logged_in_option)
1085
1098
  raise Jamf::InvalidDataError, "user_logged_in options: #{USER_LOGGED_IN.join(', ')}" unless USER_LOGGED_IN.include? logged_in_option
1099
+
1086
1100
  @reboot_options[:user_logged_in] = logged_in_option
1087
1101
  @need_to_update = true
1088
1102
  end
@@ -1095,6 +1109,7 @@ module Jamf
1095
1109
  #
1096
1110
  def reboot_message=(message)
1097
1111
  raise Jamf::InvalidDataError, 'Reboot message must be a String' unless message.is_a? String
1112
+
1098
1113
  @reboot_options[:message] = message
1099
1114
  @need_to_update = true
1100
1115
  end
@@ -1107,6 +1122,7 @@ module Jamf
1107
1122
  # @return [void] description of returned object
1108
1123
  def user_message_start=(message)
1109
1124
  raise Jamf::InvalidDataError, 'User message must be a String' unless message.is_a? String
1125
+
1110
1126
  @user_message_start = message
1111
1127
  @need_to_update = true
1112
1128
  end
@@ -1118,6 +1134,7 @@ module Jamf
1118
1134
  # @return [void] description of returned object
1119
1135
  def user_message_end=(message)
1120
1136
  raise Jamf::InvalidDataError, 'User message must be a String' unless message.is_a? String
1137
+
1121
1138
  @user_message_finish = message
1122
1139
  @need_to_update = true
1123
1140
  end
@@ -1133,6 +1150,7 @@ module Jamf
1133
1150
  #
1134
1151
  def startup_disk=(startup_disk_option)
1135
1152
  raise Jamf::InvalidDataError, "#{startup_disk_option} is not a valid Startup Disk" unless startup_disk_option.is_a? String
1153
+
1136
1154
  @reboot_options[:startup_disk] = 'Specify Local Startup Disk'
1137
1155
  self.specify_startup = startup_disk_option
1138
1156
  @need_to_update = true
@@ -1147,6 +1165,7 @@ module Jamf
1147
1165
  #
1148
1166
  def specify_startup=(startup_volume)
1149
1167
  raise Jamf::InvalidDataError, "#{startup_volume} is not a valid Startup Disk" unless startup_volume.is_a? String
1168
+
1150
1169
  @reboot_options[:specify_startup] = startup_volume
1151
1170
  @need_to_update = true
1152
1171
  end
@@ -1172,6 +1191,7 @@ module Jamf
1172
1191
  #
1173
1192
  def minutes_until_reboot=(minutes)
1174
1193
  raise Jamf::InvalidDataError, 'Minutes until reboot must be an Integer' unless minutes.is_a? Integer
1194
+
1175
1195
  @reboot_options[:minutes_until_reboot] = minutes
1176
1196
  @need_to_update = true
1177
1197
  end
@@ -1185,6 +1205,7 @@ module Jamf
1185
1205
  #
1186
1206
  def file_vault_2_reboot=(fv_bool)
1187
1207
  raise Jamf::InvalidDataError, 'FileVault 2 Reboot must be a Boolean' unless fv_bool.jss_boolean?
1208
+
1188
1209
  @reboot_options[:file_vault_2_reboot] = fv_bool
1189
1210
  @need_to_update = true
1190
1211
  end
@@ -1206,6 +1227,7 @@ module Jamf
1206
1227
  #
1207
1228
  def run_command=(command)
1208
1229
  raise Jamf::InvalidDataError, 'Command to run must be a String' unless command.is_a? String
1230
+
1209
1231
  @files_processes[:run_command] = command
1210
1232
  @need_to_update = true
1211
1233
  end
@@ -1262,7 +1284,7 @@ module Jamf
1262
1284
  #
1263
1285
  def search_by_path
1264
1286
  if @files_processes[:search_by_path].nil?
1265
- return nil
1287
+ nil
1266
1288
  else
1267
1289
  Pathname.new @files_processes[:search_by_path]
1268
1290
  end
@@ -1289,6 +1311,7 @@ module Jamf
1289
1311
  #
1290
1312
  def set_search_by_path(path, delete = false)
1291
1313
  raise Jamf::InvalidDataError, 'Path to search for must be a String or a Pathname' unless path.is_a?(String) || path.is_a?(Pathname)
1314
+
1292
1315
  @files_processes[:search_by_path] = path.to_s
1293
1316
  @files_processes[:delete_file] = delete ? true : false
1294
1317
  @need_to_update = true
@@ -1308,6 +1331,7 @@ module Jamf
1308
1331
  #
1309
1332
  def spotlight_search=(term)
1310
1333
  raise Jamf::InvalidDataError, 'Spotlight search term must be a String' unless term.is_a? String
1334
+
1311
1335
  @files_processes[:spotlight_search] = term
1312
1336
  @need_to_update = true
1313
1337
  end
@@ -1326,6 +1350,7 @@ module Jamf
1326
1350
  #
1327
1351
  def locate_file=(term)
1328
1352
  raise Jamf::InvalidDataError, 'Term to locate must be a String' unless term.is_a? String
1353
+
1329
1354
  @files_processes[:locate_file] = term
1330
1355
  @need_to_update = true
1331
1356
  end
@@ -1571,7 +1596,6 @@ module Jamf
1571
1596
  @directory_bindings
1572
1597
  end
1573
1598
 
1574
-
1575
1599
  # Remove a directory binding from this policy by name or id
1576
1600
  #
1577
1601
  # @param identifier [String,Integer] the name or id of the directory binding to remove
@@ -1596,7 +1620,6 @@ module Jamf
1596
1620
  @dock_items.map { |p| p[:name] }
1597
1621
  end
1598
1622
 
1599
-
1600
1623
  ###### Printers
1601
1624
 
1602
1625
  # Add a specific printer object to the policy.
@@ -1661,7 +1684,7 @@ module Jamf
1661
1684
 
1662
1685
  name = Jamf::DockItem.map_all_ids_to(:name, cnx: @cnx)[id]
1663
1686
 
1664
- @dock_items << {id: id, name: name, action: DOCK_ITEM_ACTIONS[action]}
1687
+ @dock_items << { id: id, name: name, action: DOCK_ITEM_ACTIONS[action] }
1665
1688
 
1666
1689
  @need_to_update = true
1667
1690
  @dock_items
@@ -1677,24 +1700,18 @@ module Jamf
1677
1700
 
1678
1701
  # @return [Array] the id's of the printers handled by the policy
1679
1702
  def printer_ids
1680
- begin
1681
- @printers.map { |p| p[:id] }
1682
- rescue TypeError
1683
- return []
1684
- end
1703
+ @printers.map { |p| p[:id] }
1704
+ rescue TypeError
1705
+ []
1685
1706
  end
1686
1707
 
1687
1708
  # @return [Array] the names of the printers handled by the policy
1688
1709
  def printer_names
1689
- begin
1690
- @printers.map { |p| p[:name] }
1691
- rescue TypeError
1692
- return []
1693
- end
1710
+ @printers.map { |p| p[:name] }
1711
+ rescue TypeError
1712
+ []
1694
1713
  end
1695
1714
 
1696
-
1697
-
1698
1715
  ###### Disk Encryption
1699
1716
 
1700
1717
  # Sets the Disk Encryption application to "Remediate" and sets the remediation key type to individual.
@@ -1703,12 +1720,12 @@ module Jamf
1703
1720
  #
1704
1721
  # @return [Void]
1705
1722
  #
1706
- def reissue_key()
1723
+ def reissue_key
1707
1724
  if @disk_encryption[:action] != DISK_ENCRYPTION_ACTIONS[:remediate]
1708
1725
  # Setting New Action
1709
1726
  hash = {
1710
1727
  action: DISK_ENCRYPTION_ACTIONS[:remediate],
1711
- remediate_key_type: "Individual"
1728
+ remediate_key_type: 'Individual'
1712
1729
  }
1713
1730
 
1714
1731
  @disk_encryption = hash
@@ -1716,12 +1733,10 @@ module Jamf
1716
1733
 
1717
1734
  else
1718
1735
  # Update
1719
- return
1736
+ nil
1720
1737
  end
1721
-
1722
1738
  end
1723
1739
 
1724
-
1725
1740
  # Sets the Disk Encryption application to "Apply" and sets the correct disk encryption configuration ID using either the name or id.
1726
1741
  #
1727
1742
  # @author Tyler Morgan
@@ -1729,7 +1744,6 @@ module Jamf
1729
1744
  # @return [Void]
1730
1745
  #
1731
1746
  def apply_encryption_configuration(identifier)
1732
-
1733
1747
  id = Jamf::DiskEncryptionConfiguration.valid_id identifier
1734
1748
 
1735
1749
  return if id.nil?
@@ -1744,14 +1758,13 @@ module Jamf
1744
1758
  @need_to_update = true
1745
1759
  end
1746
1760
 
1747
-
1748
1761
  # Removes the Disk Encryption settings associated with this specific policy.
1749
1762
  #
1750
1763
  # @author Tyler Morgan
1751
1764
  #
1752
1765
  # @return [Void]
1753
1766
  #
1754
- def remove_encryption_configuration()
1767
+ def remove_encryption_configuration
1755
1768
  hash = {
1756
1769
  action: DISK_ENCRYPTION_ACTIONS[:none]
1757
1770
  }
@@ -1774,16 +1787,16 @@ module Jamf
1774
1787
 
1775
1788
  management_data = {}
1776
1789
 
1777
- if action == :change_pw || action == :reset_pw
1778
- raise Jamf::MissingDataError, ":password must be provided when changing management account password" if opts[:password].nil?
1790
+ if %i[change_pw reset_pw].include?(action)
1791
+ raise Jamf::MissingDataError, ':password must be provided when changing management account password' if opts[:password].nil?
1779
1792
 
1780
1793
  management_data = {
1781
1794
  action: MGMT_ACCOUNT_ACTIONS[action],
1782
1795
  managed_password: opts[:password]
1783
1796
  }
1784
- elsif action == :reset_random || action == :generate_pw
1785
- raise Jamf::MissingDataError, ":password_length must be provided when setting a random password" if opts[:password_length].nil?
1786
- raise Jamf::InvalidDataError, ":password_length must be an Integer" unless opts[:password_length].is_a? Integer
1797
+ elsif %i[reset_random generate_pw].include?(action)
1798
+ raise Jamf::MissingDataError, ':password_length must be provided when setting a random password' if opts[:password_length].nil?
1799
+ raise Jamf::InvalidDataError, ':password_length must be an Integer' unless opts[:password_length].is_a? Integer
1787
1800
 
1788
1801
  management_data = {
1789
1802
  action: MGMT_ACCOUNT_ACTIONS[action],
@@ -1800,21 +1813,23 @@ module Jamf
1800
1813
  @need_to_update = true
1801
1814
 
1802
1815
  @management_account
1803
-
1804
1816
  end
1805
1817
 
1806
- # Check if management password matches provided password
1818
+ # @deprecated The API no longer sends SHA256 hashed password data, and instead
1819
+ # only has a string of asterisks, meaning we can no longer use it to validate
1820
+ # passwords before attempting to use them. Instead, the processes that use
1821
+ # the password will fail on their own if the pw is not valid.
1807
1822
  #
1808
- # @param password[String] the password that is SHA256'ed to compare to the one from the API.
1823
+ # This method remains defined for backward-compatibility with any existing
1824
+ # code that calls it. but it will always return true. Itwill be removed in
1825
+ # a future version
1809
1826
  #
1810
- # @return [Boolean] The result of the comparison of the management password and provided text.
1827
+ # @param password[String] ignored
1811
1828
  #
1812
- def verify_management_password(password)
1813
- raise Jamf::InvalidDataError, "Management password must be a string." unless password.is_a? String
1814
-
1815
- raise Jamf::UnsupportedError, "'#{@management_account[:action].to_s}' does not support management passwords." unless @management_account[:action] == MGMT_ACCOUNT_ACTIONS[:change_pw] || @management_account[:action] == MGMT_ACCOUNT_ACTIONS[:reset_pw]
1816
-
1817
- return Digest::SHA256.hexdigest(password).to_s == @management_account[:managed_password_sha256].to_s
1829
+ # @return [TrueClass] Allow the process calling this to continue.
1830
+ #
1831
+ def verify_management_password(_password = nil)
1832
+ true
1818
1833
  end
1819
1834
 
1820
1835
  ###### Actions
@@ -1829,8 +1844,10 @@ module Jamf
1829
1844
  #
1830
1845
  def run(show_output = false)
1831
1846
  return nil unless enabled?
1847
+
1832
1848
  output = Jamf::Client.run_jamf('policy', "-id #{id}", show_output)
1833
1849
  return nil if output.include? 'No policies were found for the ID'
1850
+
1834
1851
  $CHILD_STATUS.exitstatus.zero? ? true : false
1835
1852
  end
1836
1853
  alias execute run
@@ -1944,6 +1961,7 @@ module Jamf
1944
1961
 
1945
1962
  id = Jamf::Script.valid_id identifier, cnx: @cnx
1946
1963
  raise Jamf::NoSuchItemError, "No script matches '#{identifier}'" unless id
1964
+
1947
1965
  id
1948
1966
  end
1949
1967
 
@@ -1963,12 +1981,13 @@ module Jamf
1963
1981
  else Jamf::Validate.integer(opts[:position])
1964
1982
  end
1965
1983
 
1966
- # if the given position is past the end, set it to -1 (the end)
1967
- opts[:position] = -1 if opts[:position] > @directory_bindings.size
1984
+ # if the given position is past the end, set it to -1 (the end)
1985
+ opts[:position] = -1 if opts[:position] > @directory_bindings.size
1986
+
1987
+ id = Jamf::DirectoryBinding.valid_id identifier, cnx: @cnx
1988
+ raise Jamf::NoSuchItemError, "No directory binding matches '#{identifier}'" unless id
1968
1989
 
1969
- id = Jamf::DirectoryBinding.valid_id identifier, cnx: @cnx
1970
- raise Jamf::NoSuchItemError, "No directory binding matches '#{identifier}'" unless id
1971
- id
1990
+ id
1972
1991
  end
1973
1992
 
1974
1993
  # Raises an error if the printer being added isn't valid, additionally checks the options and sets defaults where possible.
@@ -1994,14 +2013,17 @@ module Jamf
1994
2013
  raise Jamf::MissingDataError, "action must be provided, must be one of :#{PRINTER_ACTIONS.keys.join(':,')}." if opts[:action].nil?
1995
2014
  raise Jamf::InvalidDataError, "action must be one of :#{PRINTER_ACTIONS.keys.join(',:')}." unless PRINTER_ACTIONS.keys.include? opts[:action]
1996
2015
 
1997
-
1998
2016
  # Checks if the make_default option is valid, and sets the default if needed.
1999
- raise Jamf::InvalidDataError, "make_default must be either true or false." unless opts[:make_default].is_a?(TrueClass) || opts[:make_default].is_a?(FalseClass) || opts[:make_default].nil?
2017
+ unless opts[:make_default].is_a?(TrueClass) || opts[:make_default].is_a?(FalseClass) || opts[:make_default].nil?
2018
+ raise Jamf::InvalidDataError,
2019
+ 'make_default must be either true or false.'
2020
+ end
2000
2021
 
2001
2022
  opts[:make_default] = false if opts[:make_default].nil?
2002
2023
 
2003
2024
  id = Jamf::Printer.valid_id identifier, cnx: @cnx
2004
2025
  raise Jamf::NoSuchItemError, "No printer matches '#{identifier}'" unless id
2026
+
2005
2027
  id
2006
2028
  end
2007
2029
 
@@ -2081,7 +2103,7 @@ module Jamf
2081
2103
 
2082
2104
  disk_encryption = obj.add_element 'disk_encryption'
2083
2105
 
2084
- @disk_encryption.each do |k,v|
2106
+ @disk_encryption.each do |k, v|
2085
2107
  disk_encryption.add_element(k.to_s).text = v.to_s
2086
2108
  end
2087
2109
 
@@ -150,7 +150,8 @@ module Jamf
150
150
  element ? element.text.to_f : model
151
151
  when nil
152
152
  return nil unless element
153
- element.text.downcase == TRUE_STRING ? true : false
153
+
154
+ element.text.downcase == TRUE_STRING
154
155
  when Array
155
156
  element ? elem_as_array(model.first, element) : []
156
157
  when Hash
@@ -176,6 +177,7 @@ module Jamf
176
177
  return unless size_elems.count == 1
177
178
  return if size_elem.has_elements?
178
179
  return unless size_elem.text.jss_integer?
180
+
179
181
  elem.delete_element size_elem
180
182
  end
181
183
 
@@ -74,15 +74,15 @@ module Jamf
74
74
  attr_reader :sticky_session
75
75
  alias sticky_session? sticky_session
76
76
  alias sticky? sticky_session
77
-
77
+
78
78
  # @return [String, nil] The current sticky_session cookie. nil unless
79
79
  # sticky_session is set to true, either as a param to 'connect' or via
80
80
  # #sticky_session=
81
81
  #
82
- # When set via .connect, the cookie is gleaned from the token creation
82
+ # When set via .connect, the cookie is gleaned from the token creation
83
83
  # reponse. When set via #sticky_session=, a HEAD request is made, and the
84
84
  # cookie will be in the response.
85
- #
85
+ #
86
86
  # Only valid when the connection is to a Jamf Cloud server.
87
87
  attr_reader :sticky_session_cookie
88
88
 
@@ -100,7 +100,7 @@ module Jamf
100
100
 
101
101
  # convert boolean-y to boolean
102
102
  value = value ? true : false
103
-
103
+
104
104
  return if @sticky_session == value
105
105
 
106
106
  if value
@@ -125,8 +125,8 @@ module Jamf
125
125
  #
126
126
  def timeout=(new_timeout)
127
127
  @timeout = new_timeout.to_i
128
- @c_cnx&.options[:timeout] = @timeout
129
- @jp_cnx&.options[:timeout] = @timeout
128
+ @c_cnx.options.timeout = @timeout if @c_cnx
129
+ @jp_cnx.options.timeout = @timeout if @jp_cnx
130
130
  end
131
131
 
132
132
  # Reset the open-connection timeout for the rest connection
@@ -137,8 +137,8 @@ module Jamf
137
137
  #
138
138
  def open_timeout=(new_timeout)
139
139
  @open_timeout = new_timeout.to_i
140
- @c_cnx&.options[:open_timeout] = @open_timeout
141
- @jp_cnx&.options[:open_timeout] = @open_timeout
140
+ @c_cnx.options.open_timeout = @open_timeout if @c_cnx
141
+ @jp_cnx.options.open_timeout = @open_timeout if @jp_cnx
142
142
  end
143
143
 
144
144
  # @return [URI::HTTPS] the base URL to the server
@@ -59,6 +59,8 @@ module Jamf
59
59
  # @return [Hash,String] the result of the get
60
60
  #
61
61
  def c_get(rsrc, format = :json, raw_json: false)
62
+ rsrc = rsrc.delete_prefix Jamf::Connection::SLASH
63
+
62
64
  validate_connected @c_cnx
63
65
  raise Jamf::InvalidDataError, 'format must be :json or :xml' unless Jamf::Connection::GET_FORMATS.include?(format)
64
66
 
@@ -92,6 +94,8 @@ module Jamf
92
94
  def c_post(rsrc, xml)
93
95
  validate_connected @c_cnx
94
96
 
97
+ rsrc = rsrc.delete_prefix Jamf::Connection::SLASH
98
+
95
99
  # convert CRs & to &#13;
96
100
  xml&.gsub!(/\r/, '&#13;')
97
101
 
@@ -125,6 +129,8 @@ module Jamf
125
129
  def c_put(rsrc, xml)
126
130
  validate_connected @c_cnx
127
131
 
132
+ rsrc = rsrc.delete_prefix Jamf::Connection::SLASH
133
+
128
134
  # convert CRs & to &#13;
129
135
  xml.gsub!(/\r/, '&#13;')
130
136
 
@@ -157,6 +163,8 @@ module Jamf
157
163
  validate_connected @c_cnx
158
164
  raise MissingDataError, 'Missing :rsrc' if rsrc.nil?
159
165
 
166
+ rsrc = rsrc.delete_prefix Jamf::Connection::SLASH
167
+
160
168
  # delete the resource
161
169
  resp =
162
170
  @c_cnx.delete(rsrc) do |req|
@@ -188,6 +196,7 @@ module Jamf
188
196
  #
189
197
  def upload(rsrc, local_file)
190
198
  validate_connected @c_cnx
199
+ rsrc = rsrc.delete_prefix Jamf::Connection::SLASH
191
200
 
192
201
  # the upload file object for faraday
193
202
  local_file = Pathname.new local_file
@@ -223,7 +232,7 @@ module Jamf
223
232
 
224
233
  cnx.options[:timeout] = @timeout
225
234
  cnx.options[:open_timeout] = @open_timeout
226
-
235
+
227
236
  cnx.request :multipart
228
237
  cnx.request :url_encoded
229
238
 
@@ -87,6 +87,8 @@ module Jamf
87
87
  MIME_JSON = 'application/json'.freeze
88
88
  MIME_XML = 'application/xml'.freeze
89
89
 
90
+ SLASH = '/'
91
+
90
92
  # Only these variables are displayed with PrettyPrint
91
93
  # This avoids, especially, the caches, which are available
92
94
  # as attr_readers
@@ -53,11 +53,12 @@ module Jamf
53
53
 
54
54
  # @param rsrc[String] the resource to get
55
55
  # (the part of the API url after the '/api/' )
56
-
56
+
57
57
  # @return [Hash] the result of the get
58
58
  #######################################################
59
59
  def jp_get(rsrc)
60
60
  validate_connected @jp_cnx
61
+ rsrc = rsrc.delete_prefix Jamf::Connection::SLASH
61
62
  resp = @jp_cnx.get(rsrc) do |req|
62
63
  # Modify the request here if needed.
63
64
  # puts "JPAPI Cookie is: #{req.headers['Cookie']}"
@@ -82,6 +83,7 @@ module Jamf
82
83
  #######################################################
83
84
  def jp_post(rsrc, data)
84
85
  validate_connected @jp_cnx
86
+ rsrc = rsrc.delete_prefix Jamf::Connection::SLASH
85
87
  resp = @jp_cnx.post(rsrc) do |req|
86
88
  req.body = data
87
89
  end
@@ -104,6 +106,7 @@ module Jamf
104
106
  #######################################################
105
107
  def jp_put(rsrc, data)
106
108
  validate_connected @jp_cnx
109
+ rsrc = rsrc.delete_prefix Jamf::Connection::SLASH
107
110
  resp = @jp_cnx.put(rsrc) do |req|
108
111
  req.body = data
109
112
  end
@@ -126,6 +129,7 @@ module Jamf
126
129
  #######################################################
127
130
  def jp_patch(rsrc, data)
128
131
  validate_connected @jp_cnx
132
+ rsrc = rsrc.delete_prefix Jamf::Connection::SLASH
129
133
  resp = @jp_cnx.patch(rsrc) do |req|
130
134
  req.body = data
131
135
  end
@@ -146,6 +150,7 @@ module Jamf
146
150
  #######################################################
147
151
  def jp_delete(rsrc)
148
152
  validate_connected @jp_cnx
153
+ rsrc = rsrc.delete_prefix Jamf::Connection::SLASH
149
154
  resp = @jp_cnx.delete rsrc
150
155
  @last_http_response = resp
151
156
  return resp.body if resp.success?
@@ -159,6 +164,7 @@ module Jamf
159
164
  # a temporary Faraday connection object
160
165
  #######################################################
161
166
  def jp_download(rsrc)
167
+ rsrc = rsrc.delete_prefix Jamf::Connection::SLASH
162
168
  temp_cnx = create_jp_connection(parse_json: false)
163
169
  resp = temp_cnx.get rsrc
164
170
  @last_http_response = resp
data/lib/jamf/version.rb CHANGED
@@ -27,6 +27,6 @@
27
27
  module Jamf
28
28
 
29
29
  ### The version of ruby-jss
30
- VERSION = '2.1.0b5'.freeze
30
+ VERSION = '2.1.1'.freeze
31
31
 
32
32
  end # module
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruby-jss
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.1.0b5
4
+ version: 2.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Chris Lasell
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2022-09-23 00:00:00.000000000 Z
13
+ date: 2022-11-09 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: CFPropertyList
@@ -824,9 +824,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
824
824
  version: 2.6.3
825
825
  required_rubygems_version: !ruby/object:Gem::Requirement
826
826
  requirements:
827
- - - ">"
827
+ - - ">="
828
828
  - !ruby/object:Gem::Version
829
- version: 1.3.1
829
+ version: '0'
830
830
  requirements: []
831
831
  rubygems_version: 3.0.3.1
832
832
  signing_key: