-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathshare_mounter.rb
executable file
·302 lines (256 loc) · 8.62 KB
/
share_mounter.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
#!/usr/bin/env ruby
require 'rubygems'
require 'json'
require 'uri'
require 'logger'
require File.expand_path(File.dirname(__FILE__) + '/ad_adapters')
# Get current logged in user
CURRENT_USER = `id -un`.strip
# Get computer name
# TODO: move this into the adapter to get the name we're actually bound as. Can be different from the computer name
COMPUTER_NAME = `scutil --get ComputerName`.strip
# Log level
LOG = Logger.new(STDOUT)
LOG.level = Logger::INFO
if ARGV.include? "-debug"
LOG.level = Logger::DEBUG
end
#####################
def main
ADAdapters.adapter = select_default_adapter
groups = ADAdapters.get_groups(CURRENT_USER, "user")
unless groups.nil? || groups.empty?
shares = find_shares_in_groups(groups)
LOG.debug "Start share mounting routine"
if shares.is_a?(Array) && !shares.empty?
shares.each do |s|
LOG.debug "Attempting to mount share: #{s.inspect}"
s.mount if s.is_a? Share
end
else
LOG.debug "No shares were found"
end
else
LOG.warn "No group membership was found for object: #{CURRENT_USER}"
end
# If multiple shares were mounted, their desktop icons sometimes will overlap each other. Tell Finder to cleanup to arrange these.
# LOG.debug "Telling Finder.app to rearrange desktop items by name"
# `osascript -e 'tell application "Finder" to clean up window of desktop by name'`
LOG.debug "ADShareMounter out."
end
def find_shares_in_groups(groups)
shares = []
if groups.empty?
LOG.warn "Warning: no group members found in #{ALL_SHARES_GROUP}"
else
groups.each do |group|
data = ADAdapters.get_info(group)
LOG.debug("Data returned from directory plugin: #{data.inspect}")
if data.nil? || data.empty?
LOG.warn "Warning: group '#{group}' has an empty info attribute"
else
begin
json_segments = data.extract_json
if json_segments
json_segments.each do |data|
obj = JSON.parse(data)
if ! obj.is_a? Hash
LOG.warn "JSON object from #{group} does not convert to a hash"
elsif ! obj.has_key? "shares"
LOG.warn "JSON object from #{group} doesn't contain a shares key"
else
case obj["shares"]
when Array
obj["shares"].each do |share|
LOG.debug "Our shares was an array"
LOG.debug "Processing share data: #{share.inspect}"
shares << Share.new(share)
end
else # Hash or String
unless obj["shares"].empty?
LOG.debug "Creating new share object with arg: #{obj["shares"].inspect}"
shares << Share.new(obj["shares"])
end
end
end
end # end json_sengments loop
else
LOG.debug "No JSON segments found"
end
rescue JSON::ParserError => e
LOG.warn "Warning: group '#{group}' has a json error: #{e}"
end # end trap
end
end
end
shares
end
def get_shares
shares = []
groups = ADAdapters.enum_groups
if groups.empty?
LOG.warn "Warning: no group members found in #{ALL_SHARES_GROUP}"
else
groups.each do |group|
data = ADAdapters.get_info(group)
if data.empty?
LOG.warn "Warning: group '#{group}' has an empty info attribute"
else
begin
json_segments = data.extract_json
json_segments.each do |data|
obj = JSON.parse(data)
if ! obj.is_a? Hash
LOG.warn "JSON object from #{group} does not convert to a hash"
elsif ! obj.has_key? "shares"
LOG.warn "JSON object from #{group} doesn't contain a shares key"
else
case obj["shares"]
when Array
obj["shares"].each do |share|
LOG.debug "Our shares was an array"
LOG.debug "Processing share data: #{share.inspect}"
member_type = (share.has_key? "member_type") ? share['member_type'] : 'user'
result = ADAdapters.check_membership(group, member_type)
LOG.debug "Result from membership check: #{result}"
if result
shares << Share.new(share)
else
LOG.debug "#{member_type} was not found to be a member of #{group}. Skipping share."
end
end
else
unless obj["shares"].empty?
LOG.debug "Creating new share object with arg: #{obj["shares"].inspect}"
member_type = (obj["shares"].has_key? "member_type") ? obj["shares"]['member_type'] : 'user'
result = ADAdapters.check_membership(group, member_type)
LOG.debug "Result from membership check: #{result}"
if result
shares << Share.new(obj["shares"])
else
LOG.debug "#{member_type} was not found to be a member of #{group}. Skipping share."
end
end
end
end
end
rescue JSON::ParserError => e
LOG.warn "Warning: group '#{group}' has a json error: #{e}"
end
end
end
end
shares
end
class String
def occurances_of(str, offset=0)
occ = []
index = 0
begin
index = self.index("}", offset+index+1)
occ << index unless index.nil?
end while index != nil
occ
end
def extract_json
json_segments = []
LOG.debug("Attempting to extract JSON data from string: #{self}")
begin
offset = 0 unless offset
first_open = self.index("{", offset)
if first_open
LOG.debug("JSON opening bracket located at position #{first_open}")
else
LOG.debug("No opening bracket found - not JSON data")
break
end
all_close = self.occurances_of('}', offset)
if first_open
LOG.debug("JSON closing bracket(s) located at position(s) #{all_close.inspect}")
else
LOG.debug("No closing brackets found - not JSON data")
return nil
end
all_close.each do |end_pos|
LOG.debug("Evaluating string from #{first_open} to #{end_pos} for valid JSON")
begin
obj = JSON.parse(self[first_open..end_pos])
rescue JSON::ParserError
LOG.debug("Nothing valid found in #{first_open} to #{end_pos}")
else
offset = end_pos
LOG.debug("Valid JSON valid found in #{first_open} to #{end_pos}. Adding segment")
json_segments << self[first_open..end_pos]
break
end
end
end while !all_close.empty?
json_segments
end
end
class Share
def initialize(arg)
@user = `id -un`.strip
case arg
when Hash
if arg.has_key? 'domain'
@domain = arg['domain']
LOG.debug "set local domain variable = #{arg['domain']}"
end
if arg.has_key? 'path'
@share = arg['path']
LOG.debug "set local share variable = #{arg['path']}"
@uri = URI.parse expand_variables(@share)
else
LOG.warn "Path key is required for a share"
return
end
@mountname = (arg.has_key? 'mountname') ? arg['mountname'] : @uri.path.split("/").last
LOG.debug "set mountname variable = #{@mountname}"
when String
@share = arg
@uri = URI.parse(@share)
end
end
def mount
user = `id -un`.strip
LOG.debug "Username we're using to mount with is #{user}"
mountpoint = "/Volumes/#{mountname}"
`mkdir -p "#{mountpoint}"`
`chmod 777 "#{mountpoint}"`
LOG.info "Mountpoint created at #{mountpoint}"
sharestring = "//\""
sharestring << "#{@domain};" if @domain
sharestring << "#{user}\""
sharestring << "@\"#{@uri.host}#{sharepath}\""
result = `mount_smbfs #{sharestring} "#{mountpoint}" 2>&1`
if $? != 0
LOG.error "Unable to mount #{sharestring} at #{mountpoint}: #{result}"
else
LOG.info "#{mountname} successfully mounted."
end
end
def mountname
expand_variables @mountname
end
def sharepath
expand_variables @uri.path
end
private
def expand_variables(str)
# Expand username variable %U
if str.include? "%U"
str.gsub!("%U", @user)
end
str
end
end
def select_default_adapter
# Assume that if the pbis tools are installed, we should use pbis
if File.exist? "/opt/pbis"
:pbis
else
:ds
end
end
main