clockwerk-opensim – Blame information for rev 1
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
1 | vero | 1 | /* |
2 | * Copyright (c) Contributors, http://opensimulator.org/ |
||
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. |
||
4 | * |
||
5 | * Redistribution and use in source and binary forms, with or without |
||
6 | * modification, are permitted provided that the following conditions are met: |
||
7 | * * Redistributions of source code must retain the above copyright |
||
8 | * notice, this list of conditions and the following disclaimer. |
||
9 | * * Redistributions in binary form must reproduce the above copyright |
||
10 | * notice, this list of conditions and the following disclaimer in the |
||
11 | * documentation and/or other materials provided with the distribution. |
||
12 | * * Neither the name of the OpenSimulator Project nor the |
||
13 | * names of its contributors may be used to endorse or promote products |
||
14 | * derived from this software without specific prior written permission. |
||
15 | * |
||
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY |
||
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
||
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
||
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY |
||
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
||
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
||
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND |
||
23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
||
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||
26 | */ |
||
27 | |||
28 | using System; |
||
29 | using System.Collections.Generic; |
||
30 | using System.Linq; |
||
31 | using System.Reflection; |
||
32 | using log4net; |
||
33 | using Nini.Config; |
||
34 | using OpenMetaverse; |
||
35 | using OpenSim.Framework; |
||
36 | |||
37 | using OpenSim.Region.Framework.Interfaces; |
||
38 | using OpenSim.Region.Framework.Scenes; |
||
39 | using OpenSim.Services.Interfaces; |
||
40 | |||
41 | using Mono.Addins; |
||
42 | using PermissionMask = OpenSim.Framework.PermissionMask; |
||
43 | |||
44 | namespace OpenSim.Region.CoreModules.World.Permissions |
||
45 | { |
||
46 | [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "PermissionsModule")] |
||
47 | public class PermissionsModule : INonSharedRegionModule, IPermissionsModule |
||
48 | { |
||
49 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
||
50 | |||
51 | protected Scene m_scene; |
||
52 | protected bool m_Enabled; |
||
53 | |||
54 | private InventoryFolderImpl m_libraryRootFolder; |
||
55 | protected InventoryFolderImpl LibraryRootFolder |
||
56 | { |
||
57 | get |
||
58 | { |
||
59 | if (m_libraryRootFolder != null) |
||
60 | return m_libraryRootFolder; |
||
61 | |||
62 | ILibraryService lib = m_scene.RequestModuleInterface<ILibraryService>(); |
||
63 | if (lib != null) |
||
64 | { |
||
65 | m_libraryRootFolder = lib.LibraryRootFolder; |
||
66 | } |
||
67 | return m_libraryRootFolder; |
||
68 | } |
||
69 | } |
||
70 | |||
71 | #region Constants |
||
72 | // These are here for testing. They will be taken out |
||
73 | |||
74 | //private uint PERM_ALL = (uint)2147483647; |
||
75 | private uint PERM_COPY = (uint)32768; |
||
76 | //private uint PERM_MODIFY = (uint)16384; |
||
77 | private uint PERM_MOVE = (uint)524288; |
||
78 | private uint PERM_TRANS = (uint)8192; |
||
79 | private uint PERM_LOCKED = (uint)540672; |
||
80 | |||
81 | /// <value> |
||
82 | /// Different user set names that come in from the configuration file. |
||
83 | /// </value> |
||
84 | enum UserSet |
||
85 | { |
||
86 | All, |
||
87 | Administrators |
||
88 | }; |
||
89 | |||
90 | #endregion |
||
91 | |||
92 | #region Bypass Permissions / Debug Permissions Stuff |
||
93 | |||
94 | // Bypasses the permissions engine |
||
95 | private bool m_bypassPermissions = true; |
||
96 | private bool m_bypassPermissionsValue = true; |
||
97 | private bool m_propagatePermissions = false; |
||
98 | private bool m_debugPermissions = false; |
||
99 | private bool m_allowGridGods = false; |
||
100 | private bool m_RegionOwnerIsGod = false; |
||
101 | private bool m_RegionManagerIsGod = false; |
||
102 | private bool m_ParcelOwnerIsGod = false; |
||
103 | |||
104 | private bool m_SimpleBuildPermissions = false; |
||
105 | |||
106 | /// <value> |
||
107 | /// The set of users that are allowed to create scripts. This is only active if permissions are not being |
||
108 | /// bypassed. This overrides normal permissions. |
||
109 | /// </value> |
||
110 | private UserSet m_allowedScriptCreators = UserSet.All; |
||
111 | |||
112 | /// <value> |
||
113 | /// The set of users that are allowed to edit (save) scripts. This is only active if |
||
114 | /// permissions are not being bypassed. This overrides normal permissions.- |
||
115 | /// </value> |
||
116 | private UserSet m_allowedScriptEditors = UserSet.All; |
||
117 | |||
118 | private Dictionary<string, bool> GrantLSL = new Dictionary<string, bool>(); |
||
119 | private Dictionary<string, bool> GrantCS = new Dictionary<string, bool>(); |
||
120 | private Dictionary<string, bool> GrantVB = new Dictionary<string, bool>(); |
||
121 | private Dictionary<string, bool> GrantJS = new Dictionary<string, bool>(); |
||
122 | private Dictionary<string, bool> GrantYP = new Dictionary<string, bool>(); |
||
123 | |||
124 | private IFriendsModule m_friendsModule; |
||
125 | private IFriendsModule FriendsModule |
||
126 | { |
||
127 | get |
||
128 | { |
||
129 | if (m_friendsModule == null) |
||
130 | m_friendsModule = m_scene.RequestModuleInterface<IFriendsModule>(); |
||
131 | return m_friendsModule; |
||
132 | } |
||
133 | } |
||
134 | private IGroupsModule m_groupsModule; |
||
135 | private IGroupsModule GroupsModule |
||
136 | { |
||
137 | get |
||
138 | { |
||
139 | if (m_groupsModule == null) |
||
140 | m_groupsModule = m_scene.RequestModuleInterface<IGroupsModule>(); |
||
141 | return m_groupsModule; |
||
142 | } |
||
143 | } |
||
144 | |||
145 | private IMoapModule m_moapModule; |
||
146 | private IMoapModule MoapModule |
||
147 | { |
||
148 | get |
||
149 | { |
||
150 | if (m_moapModule == null) |
||
151 | m_moapModule = m_scene.RequestModuleInterface<IMoapModule>(); |
||
152 | return m_moapModule; |
||
153 | } |
||
154 | } |
||
155 | #endregion |
||
156 | |||
157 | #region INonSharedRegionModule Members |
||
158 | |||
159 | public void Initialise(IConfigSource config) |
||
160 | { |
||
161 | string permissionModules = Util.GetConfigVarFromSections<string>(config, "permissionmodules", |
||
162 | new string[] { "Startup", "Permissions" }, "DefaultPermissionsModule"); |
||
163 | |||
164 | List<string> modules = new List<string>(permissionModules.Split(',').Select(m => m.Trim())); |
||
165 | |||
166 | if (!modules.Contains("DefaultPermissionsModule")) |
||
167 | return; |
||
168 | |||
169 | m_Enabled = true; |
||
170 | |||
171 | m_allowGridGods = Util.GetConfigVarFromSections<bool>(config, "allow_grid_gods", |
||
172 | new string[] { "Startup", "Permissions" }, false); |
||
173 | m_bypassPermissions = !Util.GetConfigVarFromSections<bool>(config, "serverside_object_permissions", |
||
174 | new string[] { "Startup", "Permissions" }, true); |
||
175 | m_propagatePermissions = Util.GetConfigVarFromSections<bool>(config, "propagate_permissions", |
||
176 | new string[] { "Startup", "Permissions" }, true); |
||
177 | m_RegionOwnerIsGod = Util.GetConfigVarFromSections<bool>(config, "region_owner_is_god", |
||
178 | new string[] { "Startup", "Permissions" }, true); |
||
179 | m_RegionManagerIsGod = Util.GetConfigVarFromSections<bool>(config, "region_manager_is_god", |
||
180 | new string[] { "Startup", "Permissions" }, false); |
||
181 | m_ParcelOwnerIsGod = Util.GetConfigVarFromSections<bool>(config, "parcel_owner_is_god", |
||
182 | new string[] { "Startup", "Permissions" }, true); |
||
183 | |||
184 | m_SimpleBuildPermissions = Util.GetConfigVarFromSections<bool>(config, "simple_build_permissions", |
||
185 | new string[] { "Startup", "Permissions" }, false); |
||
186 | |||
187 | m_allowedScriptCreators |
||
188 | = ParseUserSetConfigSetting(config, "allowed_script_creators", m_allowedScriptCreators); |
||
189 | m_allowedScriptEditors |
||
190 | = ParseUserSetConfigSetting(config, "allowed_script_editors", m_allowedScriptEditors); |
||
191 | |||
192 | if (m_bypassPermissions) |
||
193 | m_log.Info("[PERMISSIONS]: serverside_object_permissions = false in ini file so disabling all region service permission checks"); |
||
194 | else |
||
195 | m_log.Debug("[PERMISSIONS]: Enabling all region service permission checks"); |
||
196 | |||
197 | string grant = Util.GetConfigVarFromSections<string>(config, "GrantLSL", |
||
198 | new string[] { "Startup", "Permissions" }, string.Empty); |
||
199 | if (grant.Length > 0) |
||
200 | { |
||
201 | foreach (string uuidl in grant.Split(',')) |
||
202 | { |
||
203 | string uuid = uuidl.Trim(" \t".ToCharArray()); |
||
204 | GrantLSL.Add(uuid, true); |
||
205 | } |
||
206 | } |
||
207 | |||
208 | grant = Util.GetConfigVarFromSections<string>(config, "GrantCS", |
||
209 | new string[] { "Startup", "Permissions" }, string.Empty); |
||
210 | if (grant.Length > 0) |
||
211 | { |
||
212 | foreach (string uuidl in grant.Split(',')) |
||
213 | { |
||
214 | string uuid = uuidl.Trim(" \t".ToCharArray()); |
||
215 | GrantCS.Add(uuid, true); |
||
216 | } |
||
217 | } |
||
218 | |||
219 | grant = Util.GetConfigVarFromSections<string>(config, "GrantVB", |
||
220 | new string[] { "Startup", "Permissions" }, string.Empty); |
||
221 | if (grant.Length > 0) |
||
222 | { |
||
223 | foreach (string uuidl in grant.Split(',')) |
||
224 | { |
||
225 | string uuid = uuidl.Trim(" \t".ToCharArray()); |
||
226 | GrantVB.Add(uuid, true); |
||
227 | } |
||
228 | } |
||
229 | |||
230 | grant = Util.GetConfigVarFromSections<string>(config, "GrantJS", |
||
231 | new string[] { "Startup", "Permissions" }, string.Empty); |
||
232 | if (grant.Length > 0) |
||
233 | { |
||
234 | foreach (string uuidl in grant.Split(',')) |
||
235 | { |
||
236 | string uuid = uuidl.Trim(" \t".ToCharArray()); |
||
237 | GrantJS.Add(uuid, true); |
||
238 | } |
||
239 | } |
||
240 | |||
241 | grant = Util.GetConfigVarFromSections<string>(config, "GrantYP", |
||
242 | new string[] { "Startup", "Permissions" }, string.Empty); |
||
243 | if (grant.Length > 0) |
||
244 | { |
||
245 | foreach (string uuidl in grant.Split(',')) |
||
246 | { |
||
247 | string uuid = uuidl.Trim(" \t".ToCharArray()); |
||
248 | GrantYP.Add(uuid, true); |
||
249 | } |
||
250 | } |
||
251 | } |
||
252 | |||
253 | public void AddRegion(Scene scene) |
||
254 | { |
||
255 | if (!m_Enabled) |
||
256 | return; |
||
257 | |||
258 | m_scene = scene; |
||
259 | |||
260 | scene.RegisterModuleInterface<IPermissionsModule>(this); |
||
261 | |||
262 | //Register functions with Scene External Checks! |
||
263 | m_scene.Permissions.OnBypassPermissions += BypassPermissions; |
||
264 | m_scene.Permissions.OnSetBypassPermissions += SetBypassPermissions; |
||
265 | m_scene.Permissions.OnPropagatePermissions += PropagatePermissions; |
||
266 | m_scene.Permissions.OnGenerateClientFlags += GenerateClientFlags; |
||
267 | m_scene.Permissions.OnAbandonParcel += CanAbandonParcel; |
||
268 | m_scene.Permissions.OnReclaimParcel += CanReclaimParcel; |
||
269 | m_scene.Permissions.OnDeedParcel += CanDeedParcel; |
||
270 | m_scene.Permissions.OnDeedObject += CanDeedObject; |
||
271 | m_scene.Permissions.OnIsGod += IsGod; |
||
272 | m_scene.Permissions.OnIsGridGod += IsGridGod; |
||
273 | m_scene.Permissions.OnIsAdministrator += IsAdministrator; |
||
274 | m_scene.Permissions.OnDuplicateObject += CanDuplicateObject; |
||
275 | m_scene.Permissions.OnDeleteObject += CanDeleteObject; |
||
276 | m_scene.Permissions.OnEditObject += CanEditObject; |
||
277 | m_scene.Permissions.OnEditParcelProperties += CanEditParcelProperties; |
||
278 | m_scene.Permissions.OnInstantMessage += CanInstantMessage; |
||
279 | m_scene.Permissions.OnInventoryTransfer += CanInventoryTransfer; |
||
280 | m_scene.Permissions.OnIssueEstateCommand += CanIssueEstateCommand; |
||
281 | m_scene.Permissions.OnMoveObject += CanMoveObject; |
||
282 | m_scene.Permissions.OnObjectEntry += CanObjectEntry; |
||
283 | m_scene.Permissions.OnReturnObjects += CanReturnObjects; |
||
284 | m_scene.Permissions.OnRezObject += CanRezObject; |
||
285 | m_scene.Permissions.OnRunConsoleCommand += CanRunConsoleCommand; |
||
286 | m_scene.Permissions.OnRunScript += CanRunScript; |
||
287 | m_scene.Permissions.OnCompileScript += CanCompileScript; |
||
288 | m_scene.Permissions.OnSellParcel += CanSellParcel; |
||
289 | m_scene.Permissions.OnTakeObject += CanTakeObject; |
||
290 | m_scene.Permissions.OnTakeCopyObject += CanTakeCopyObject; |
||
291 | m_scene.Permissions.OnTerraformLand += CanTerraformLand; |
||
292 | m_scene.Permissions.OnLinkObject += CanLinkObject; |
||
293 | m_scene.Permissions.OnDelinkObject += CanDelinkObject; |
||
294 | m_scene.Permissions.OnBuyLand += CanBuyLand; |
||
295 | |||
296 | m_scene.Permissions.OnViewNotecard += CanViewNotecard; |
||
297 | m_scene.Permissions.OnViewScript += CanViewScript; |
||
298 | m_scene.Permissions.OnEditNotecard += CanEditNotecard; |
||
299 | m_scene.Permissions.OnEditScript += CanEditScript; |
||
300 | |||
301 | m_scene.Permissions.OnCreateObjectInventory += CanCreateObjectInventory; |
||
302 | m_scene.Permissions.OnEditObjectInventory += CanEditObjectInventory; |
||
303 | m_scene.Permissions.OnCopyObjectInventory += CanCopyObjectInventory; |
||
304 | m_scene.Permissions.OnDeleteObjectInventory += CanDeleteObjectInventory; |
||
305 | m_scene.Permissions.OnResetScript += CanResetScript; |
||
306 | |||
307 | m_scene.Permissions.OnCreateUserInventory += CanCreateUserInventory; |
||
308 | m_scene.Permissions.OnCopyUserInventory += CanCopyUserInventory; |
||
309 | m_scene.Permissions.OnEditUserInventory += CanEditUserInventory; |
||
310 | m_scene.Permissions.OnDeleteUserInventory += CanDeleteUserInventory; |
||
311 | |||
312 | m_scene.Permissions.OnTeleport += CanTeleport; |
||
313 | |||
314 | m_scene.Permissions.OnControlPrimMedia += CanControlPrimMedia; |
||
315 | m_scene.Permissions.OnInteractWithPrimMedia += CanInteractWithPrimMedia; |
||
316 | |||
317 | m_scene.AddCommand("Users", this, "bypass permissions", |
||
318 | "bypass permissions <true / false>", |
||
319 | "Bypass permission checks", |
||
320 | HandleBypassPermissions); |
||
321 | |||
322 | m_scene.AddCommand("Users", this, "force permissions", |
||
323 | "force permissions <true / false>", |
||
324 | "Force permissions on or off", |
||
325 | HandleForcePermissions); |
||
326 | |||
327 | m_scene.AddCommand("Debug", this, "debug permissions", |
||
328 | "debug permissions <true / false>", |
||
329 | "Turn on permissions debugging", |
||
330 | HandleDebugPermissions); |
||
331 | |||
332 | } |
||
333 | |||
334 | public void RegionLoaded(Scene scene) |
||
335 | { |
||
336 | } |
||
337 | |||
338 | public void RemoveRegion(Scene scene) |
||
339 | { |
||
340 | if (!m_Enabled) |
||
341 | return; |
||
342 | |||
343 | m_scene.UnregisterModuleInterface<IPermissionsModule>(this); |
||
344 | } |
||
345 | |||
346 | public void Close() |
||
347 | { |
||
348 | } |
||
349 | |||
350 | public string Name |
||
351 | { |
||
352 | get { return "PermissionsModule"; } |
||
353 | } |
||
354 | |||
355 | public Type ReplaceableInterface |
||
356 | { |
||
357 | get { return null; } |
||
358 | } |
||
359 | |||
360 | #endregion |
||
361 | |||
362 | #region Console command handlers |
||
363 | |||
364 | public void HandleBypassPermissions(string module, string[] args) |
||
365 | { |
||
366 | if (m_scene.ConsoleScene() != null && |
||
367 | m_scene.ConsoleScene() != m_scene) |
||
368 | { |
||
369 | return; |
||
370 | } |
||
371 | |||
372 | if (args.Length > 2) |
||
373 | { |
||
374 | bool val; |
||
375 | |||
376 | if (!bool.TryParse(args[2], out val)) |
||
377 | return; |
||
378 | |||
379 | m_bypassPermissions = val; |
||
380 | |||
381 | m_log.InfoFormat( |
||
382 | "[PERMISSIONS]: Set permissions bypass to {0} for {1}", |
||
383 | m_bypassPermissions, m_scene.RegionInfo.RegionName); |
||
384 | } |
||
385 | } |
||
386 | |||
387 | public void HandleForcePermissions(string module, string[] args) |
||
388 | { |
||
389 | if (m_scene.ConsoleScene() != null && |
||
390 | m_scene.ConsoleScene() != m_scene) |
||
391 | { |
||
392 | return; |
||
393 | } |
||
394 | |||
395 | if (!m_bypassPermissions) |
||
396 | { |
||
397 | m_log.Error("[PERMISSIONS] Permissions can't be forced unless they are bypassed first"); |
||
398 | return; |
||
399 | } |
||
400 | |||
401 | if (args.Length > 2) |
||
402 | { |
||
403 | bool val; |
||
404 | |||
405 | if (!bool.TryParse(args[2], out val)) |
||
406 | return; |
||
407 | |||
408 | m_bypassPermissionsValue = val; |
||
409 | |||
410 | m_log.InfoFormat("[PERMISSIONS] Forced permissions to {0} in {1}", m_bypassPermissionsValue, m_scene.RegionInfo.RegionName); |
||
411 | } |
||
412 | } |
||
413 | |||
414 | public void HandleDebugPermissions(string module, string[] args) |
||
415 | { |
||
416 | if (m_scene.ConsoleScene() != null && |
||
417 | m_scene.ConsoleScene() != m_scene) |
||
418 | { |
||
419 | return; |
||
420 | } |
||
421 | |||
422 | if (args.Length > 2) |
||
423 | { |
||
424 | bool val; |
||
425 | |||
426 | if (!bool.TryParse(args[2], out val)) |
||
427 | return; |
||
428 | |||
429 | m_debugPermissions = val; |
||
430 | |||
431 | m_log.InfoFormat("[PERMISSIONS] Set permissions debugging to {0} in {1}", m_debugPermissions, m_scene.RegionInfo.RegionName); |
||
432 | } |
||
433 | } |
||
434 | |||
435 | #endregion |
||
436 | |||
437 | #region Helper Functions |
||
438 | protected void SendPermissionError(UUID user, string reason) |
||
439 | { |
||
440 | m_scene.EventManager.TriggerPermissionError(user, reason); |
||
441 | } |
||
442 | |||
443 | protected void DebugPermissionInformation(string permissionCalled) |
||
444 | { |
||
445 | if (m_debugPermissions) |
||
446 | m_log.Debug("[PERMISSIONS]: " + permissionCalled + " was called from " + m_scene.RegionInfo.RegionName); |
||
447 | } |
||
448 | |||
449 | /// <summary> |
||
450 | /// Checks if the given group is active and if the user is a group member |
||
451 | /// with the powers requested (powers = 0 for no powers check) |
||
452 | /// </summary> |
||
453 | /// <param name="groupID"></param> |
||
454 | /// <param name="userID"></param> |
||
455 | /// <param name="powers"></param> |
||
456 | /// <returns></returns> |
||
457 | protected bool IsGroupMember(UUID groupID, UUID userID, ulong powers) |
||
458 | { |
||
459 | if (null == GroupsModule) |
||
460 | return false; |
||
461 | |||
462 | GroupMembershipData gmd = GroupsModule.GetMembershipData(groupID, userID); |
||
463 | |||
464 | if (gmd != null) |
||
465 | { |
||
466 | if (((gmd.GroupPowers != 0) && powers == 0) || (gmd.GroupPowers & powers) == powers) |
||
467 | return true; |
||
468 | } |
||
469 | |||
470 | return false; |
||
471 | } |
||
472 | |||
473 | /// <summary> |
||
474 | /// Parse a user set configuration setting |
||
475 | /// </summary> |
||
476 | /// <param name="config"></param> |
||
477 | /// <param name="settingName"></param> |
||
478 | /// <param name="defaultValue">The default value for this attribute</param> |
||
479 | /// <returns>The parsed value</returns> |
||
480 | private static UserSet ParseUserSetConfigSetting(IConfigSource config, string settingName, UserSet defaultValue) |
||
481 | { |
||
482 | UserSet userSet = defaultValue; |
||
483 | |||
484 | string rawSetting = Util.GetConfigVarFromSections<string>(config, settingName, |
||
485 | new string[] {"Startup", "Permissions"}, defaultValue.ToString()); |
||
486 | |||
487 | // Temporary measure to allow 'gods' to be specified in config for consistency's sake. In the long term |
||
488 | // this should disappear. |
||
489 | if ("gods" == rawSetting.ToLower()) |
||
490 | rawSetting = UserSet.Administrators.ToString(); |
||
491 | |||
492 | // Doing it this was so that we can do a case insensitive conversion |
||
493 | try |
||
494 | { |
||
495 | userSet = (UserSet)Enum.Parse(typeof(UserSet), rawSetting, true); |
||
496 | } |
||
497 | catch |
||
498 | { |
||
499 | m_log.ErrorFormat( |
||
500 | "[PERMISSIONS]: {0} is not a valid {1} value, setting to {2}", |
||
501 | rawSetting, settingName, userSet); |
||
502 | } |
||
503 | |||
504 | m_log.DebugFormat("[PERMISSIONS]: {0} {1}", settingName, userSet); |
||
505 | |||
506 | return userSet; |
||
507 | } |
||
508 | |||
509 | /// <summary> |
||
510 | /// Is the user regarded as an administrator? |
||
511 | /// </summary> |
||
512 | /// <param name="user"></param> |
||
513 | /// <returns></returns> |
||
514 | protected bool IsAdministrator(UUID user) |
||
515 | { |
||
516 | if (user == UUID.Zero) |
||
517 | return false; |
||
518 | |||
519 | if (m_scene.RegionInfo.EstateSettings.EstateOwner == user && m_RegionOwnerIsGod) |
||
520 | return true; |
||
521 | |||
522 | if (IsEstateManager(user) && m_RegionManagerIsGod) |
||
523 | return true; |
||
524 | |||
525 | if (IsGridGod(user, null)) |
||
526 | return true; |
||
527 | |||
528 | return false; |
||
529 | } |
||
530 | |||
531 | /// <summary> |
||
532 | /// Is the given user a God throughout the grid (not just in the current scene)? |
||
533 | /// </summary> |
||
534 | /// <param name="user">The user</param> |
||
535 | /// <param name="scene">Unused, can be null</param> |
||
536 | /// <returns></returns> |
||
537 | protected bool IsGridGod(UUID user, Scene scene) |
||
538 | { |
||
539 | DebugPermissionInformation(MethodInfo.GetCurrentMethod().Name); |
||
540 | if (m_bypassPermissions) return m_bypassPermissionsValue; |
||
541 | |||
542 | if (user == UUID.Zero) return false; |
||
543 | |||
544 | if (m_allowGridGods) |
||
545 | { |
||
546 | ScenePresence sp = m_scene.GetScenePresence(user); |
||
547 | if (sp != null) |
||
548 | return (sp.UserLevel >= 200); |
||
549 | |||
550 | UserAccount account = m_scene.UserAccountService.GetUserAccount(m_scene.RegionInfo.ScopeID, user); |
||
551 | if (account != null) |
||
552 | return (account.UserLevel >= 200); |
||
553 | } |
||
554 | |||
555 | return false; |
||
556 | } |
||
557 | |||
558 | protected bool IsFriendWithPerms(UUID user, UUID objectOwner) |
||
559 | { |
||
560 | if (user == UUID.Zero) |
||
561 | return false; |
||
562 | |||
563 | if (FriendsModule == null) |
||
564 | return false; |
||
565 | |||
566 | int friendPerms = FriendsModule.GetRightsGrantedByFriend(user, objectOwner); |
||
567 | return (friendPerms & (int)FriendRights.CanModifyObjects) != 0; |
||
568 | } |
||
569 | |||
570 | protected bool IsEstateManager(UUID user) |
||
571 | { |
||
572 | if (user == UUID.Zero) return false; |
||
573 | |||
574 | return m_scene.RegionInfo.EstateSettings.IsEstateManagerOrOwner(user); |
||
575 | } |
||
576 | |||
577 | #endregion |
||
578 | |||
579 | public bool PropagatePermissions() |
||
580 | { |
||
581 | if (m_bypassPermissions) |
||
582 | return false; |
||
583 | |||
584 | return m_propagatePermissions; |
||
585 | } |
||
586 | |||
587 | public bool BypassPermissions() |
||
588 | { |
||
589 | return m_bypassPermissions; |
||
590 | } |
||
591 | |||
592 | public void SetBypassPermissions(bool value) |
||
593 | { |
||
594 | m_bypassPermissions=value; |
||
595 | } |
||
596 | |||
597 | #region Object Permissions |
||
598 | |||
599 | public uint GenerateClientFlags(UUID user, UUID objID) |
||
600 | { |
||
601 | // Here's the way this works, |
||
602 | // ObjectFlags and Permission flags are two different enumerations |
||
603 | // ObjectFlags, however, tells the client to change what it will allow the user to do. |
||
604 | // So, that means that all of the permissions type ObjectFlags are /temporary/ and only |
||
605 | // supposed to be set when customizing the objectflags for the client. |
||
606 | |||
607 | // These temporary objectflags get computed and added in this function based on the |
||
608 | // Permission mask that's appropriate! |
||
609 | // Outside of this method, they should never be added to objectflags! |
||
610 | // -teravus |
||
611 | |||
612 | SceneObjectPart task = m_scene.GetSceneObjectPart(objID); |
||
613 | |||
614 | // this shouldn't ever happen.. return no permissions/objectflags. |
||
615 | if (task == null) |
||
616 | return (uint)0; |
||
617 | |||
618 | uint objflags = task.GetEffectiveObjectFlags(); |
||
619 | UUID objectOwner = task.OwnerID; |
||
620 | |||
621 | |||
622 | // Remove any of the objectFlags that are temporary. These will get added back if appropriate |
||
623 | // in the next bit of code |
||
624 | |||
625 | // libomv will moan about PrimFlags.ObjectYouOfficer being |
||
626 | // deprecated |
||
627 | #pragma warning disable 0612 |
||
628 | objflags &= (uint) |
||
629 | ~(PrimFlags.ObjectCopy | // Tells client you can copy the object |
||
630 | PrimFlags.ObjectModify | // tells client you can modify the object |
||
631 | PrimFlags.ObjectMove | // tells client that you can move the object (only, no mod) |
||
632 | PrimFlags.ObjectTransfer | // tells the client that you can /take/ the object if you don't own it |
||
633 | PrimFlags.ObjectYouOwner | // Tells client that you're the owner of the object |
||
634 | PrimFlags.ObjectAnyOwner | // Tells client that someone owns the object |
||
635 | PrimFlags.ObjectOwnerModify | // Tells client that you're the owner of the object |
||
636 | PrimFlags.ObjectYouOfficer // Tells client that you've got group object editing permission. Used when ObjectGroupOwned is set |
||
637 | ); |
||
638 | #pragma warning restore 0612 |
||
639 | |||
640 | // Creating the three ObjectFlags options for this method to choose from. |
||
641 | // Customize the OwnerMask |
||
642 | uint objectOwnerMask = ApplyObjectModifyMasks(task.OwnerMask, objflags); |
||
643 | objectOwnerMask |= (uint)PrimFlags.ObjectYouOwner | (uint)PrimFlags.ObjectAnyOwner | (uint)PrimFlags.ObjectOwnerModify; |
||
644 | |||
645 | // Customize the GroupMask |
||
646 | uint objectGroupMask = ApplyObjectModifyMasks(task.GroupMask, objflags); |
||
647 | |||
648 | // Customize the EveryoneMask |
||
649 | uint objectEveryoneMask = ApplyObjectModifyMasks(task.EveryoneMask, objflags); |
||
650 | if (objectOwner != UUID.Zero) |
||
651 | objectEveryoneMask |= (uint)PrimFlags.ObjectAnyOwner; |
||
652 | |||
653 | PermissionClass permissionClass = GetPermissionClass(user, task); |
||
654 | |||
655 | switch (permissionClass) |
||
656 | { |
||
657 | case PermissionClass.Owner: |
||
658 | return objectOwnerMask; |
||
659 | case PermissionClass.Group: |
||
660 | return objectGroupMask | objectEveryoneMask; |
||
661 | case PermissionClass.Everyone: |
||
662 | default: |
||
663 | return objectEveryoneMask; |
||
664 | } |
||
665 | } |
||
666 | |||
667 | private uint ApplyObjectModifyMasks(uint setPermissionMask, uint objectFlagsMask) |
||
668 | { |
||
669 | // We are adding the temporary objectflags to the object's objectflags based on the |
||
670 | // permission flag given. These change the F flags on the client. |
||
671 | |||
672 | if ((setPermissionMask & (uint)PermissionMask.Copy) != 0) |
||
673 | { |
||
674 | objectFlagsMask |= (uint)PrimFlags.ObjectCopy; |
||
675 | } |
||
676 | |||
677 | if ((setPermissionMask & (uint)PermissionMask.Move) != 0) |
||
678 | { |
||
679 | objectFlagsMask |= (uint)PrimFlags.ObjectMove; |
||
680 | } |
||
681 | |||
682 | if ((setPermissionMask & (uint)PermissionMask.Modify) != 0) |
||
683 | { |
||
684 | objectFlagsMask |= (uint)PrimFlags.ObjectModify; |
||
685 | } |
||
686 | |||
687 | if ((setPermissionMask & (uint)PermissionMask.Transfer) != 0) |
||
688 | { |
||
689 | objectFlagsMask |= (uint)PrimFlags.ObjectTransfer; |
||
690 | } |
||
691 | |||
692 | return objectFlagsMask; |
||
693 | } |
||
694 | |||
695 | public PermissionClass GetPermissionClass(UUID user, SceneObjectPart obj) |
||
696 | { |
||
697 | if (obj == null) |
||
698 | return PermissionClass.Everyone; |
||
699 | |||
700 | if (m_bypassPermissions) |
||
701 | return PermissionClass.Owner; |
||
702 | |||
703 | // Object owners should be able to edit their own content |
||
704 | UUID objectOwner = obj.OwnerID; |
||
705 | if (user == objectOwner) |
||
706 | return PermissionClass.Owner; |
||
707 | |||
708 | if (IsFriendWithPerms(user, objectOwner)) |
||
709 | return PermissionClass.Owner; |
||
710 | |||
711 | // Estate users should be able to edit anything in the sim if RegionOwnerIsGod is set |
||
712 | if (m_RegionOwnerIsGod && IsEstateManager(user) && !IsAdministrator(objectOwner)) |
||
713 | return PermissionClass.Owner; |
||
714 | |||
715 | // Admin should be able to edit anything in the sim (including admin objects) |
||
716 | if (IsAdministrator(user)) |
||
717 | return PermissionClass.Owner; |
||
718 | |||
719 | // Users should be able to edit what is over their land. |
||
720 | Vector3 taskPos = obj.AbsolutePosition; |
||
721 | ILandObject parcel = m_scene.LandChannel.GetLandObject(taskPos.X, taskPos.Y); |
||
722 | if (parcel != null && parcel.LandData.OwnerID == user && m_ParcelOwnerIsGod) |
||
723 | { |
||
724 | // Admin objects should not be editable by the above |
||
725 | if (!IsAdministrator(objectOwner)) |
||
726 | return PermissionClass.Owner; |
||
727 | } |
||
728 | |||
729 | // Group permissions |
||
730 | if ((obj.GroupID != UUID.Zero) && IsGroupMember(obj.GroupID, user, 0)) |
||
731 | return PermissionClass.Group; |
||
732 | |||
733 | return PermissionClass.Everyone; |
||
734 | } |
||
735 | |||
736 | /// <summary> |
||
737 | /// General permissions checks for any operation involving an object. These supplement more specific checks |
||
738 | /// implemented by callers. |
||
739 | /// </summary> |
||
740 | /// <param name="currentUser"></param> |
||
741 | /// <param name="objId">This is a scene object group UUID</param> |
||
742 | /// <param name="denyOnLocked"></param> |
||
743 | /// <returns></returns> |
||
744 | protected bool GenericObjectPermission(UUID currentUser, UUID objId, bool denyOnLocked) |
||
745 | { |
||
746 | // Default: deny |
||
747 | bool permission = false; |
||
748 | bool locked = false; |
||
749 | |||
750 | SceneObjectPart part = m_scene.GetSceneObjectPart(objId); |
||
751 | |||
752 | if (part == null) |
||
753 | return false; |
||
754 | |||
755 | SceneObjectGroup group = part.ParentGroup; |
||
756 | |||
757 | UUID objectOwner = group.OwnerID; |
||
758 | locked = ((group.RootPart.OwnerMask & PERM_LOCKED) == 0); |
||
759 | |||
760 | // People shouldn't be able to do anything with locked objects, except the Administrator |
||
761 | // The 'set permissions' runs through a different permission check, so when an object owner |
||
762 | // sets an object locked, the only thing that they can do is unlock it. |
||
763 | // |
||
764 | // Nobody but the object owner can set permissions on an object |
||
765 | // |
||
766 | if (locked && (!IsAdministrator(currentUser)) && denyOnLocked) |
||
767 | { |
||
768 | return false; |
||
769 | } |
||
770 | |||
771 | // Object owners should be able to edit their own content |
||
772 | if (currentUser == objectOwner) |
||
773 | { |
||
774 | // there is no way that later code can change this back to false |
||
775 | // so just return true immediately and short circuit the more |
||
776 | // expensive group checks |
||
777 | return true; |
||
778 | |||
779 | //permission = true; |
||
780 | } |
||
781 | else if (group.IsAttachment) |
||
782 | { |
||
783 | permission = false; |
||
784 | } |
||
785 | |||
786 | // m_log.DebugFormat( |
||
787 | // "[PERMISSIONS]: group.GroupID = {0}, part.GroupMask = {1}, isGroupMember = {2} for {3}", |
||
788 | // group.GroupID, |
||
789 | // m_scene.GetSceneObjectPart(objId).GroupMask, |
||
790 | // IsGroupMember(group.GroupID, currentUser, 0), |
||
791 | // currentUser); |
||
792 | |||
793 | // Group members should be able to edit group objects |
||
794 | if ((group.GroupID != UUID.Zero) |
||
795 | && ((m_scene.GetSceneObjectPart(objId).GroupMask & (uint)PermissionMask.Modify) != 0) |
||
796 | && IsGroupMember(group.GroupID, currentUser, 0)) |
||
797 | { |
||
798 | // Return immediately, so that the administrator can shares group objects |
||
799 | return true; |
||
800 | } |
||
801 | |||
802 | // Friends with benefits should be able to edit the objects too |
||
803 | if (IsFriendWithPerms(currentUser, objectOwner)) |
||
804 | // Return immediately, so that the administrator can share objects with friends |
||
805 | return true; |
||
806 | |||
807 | // Users should be able to edit what is over their land. |
||
808 | ILandObject parcel = m_scene.LandChannel.GetLandObject(group.AbsolutePosition.X, group.AbsolutePosition.Y); |
||
809 | if ((parcel != null) && (parcel.LandData.OwnerID == currentUser)) |
||
810 | { |
||
811 | permission = true; |
||
812 | } |
||
813 | |||
814 | // Estate users should be able to edit anything in the sim |
||
815 | if (IsEstateManager(currentUser)) |
||
816 | { |
||
817 | permission = true; |
||
818 | } |
||
819 | |||
820 | // Admin objects should not be editable by the above |
||
821 | if (IsAdministrator(objectOwner)) |
||
822 | { |
||
823 | permission = false; |
||
824 | } |
||
825 | |||
826 | // Admin should be able to edit anything in the sim (including admin objects) |
||
827 | if (IsAdministrator(currentUser)) |
||
828 | { |
||
829 | permission = true; |
||
830 | } |
||
831 | |||
832 | return permission; |
||
833 | } |
||
834 | |||
835 | #endregion |
||
836 | |||
837 | #region Generic Permissions |
||
838 | protected bool GenericCommunicationPermission(UUID user, UUID target) |
||
839 | { |
||
840 | // Setting this to true so that cool stuff can happen until we define what determines Generic Communication Permission |
||
841 | bool permission = true; |
||
842 | string reason = "Only registered users may communicate with another account."; |
||
843 | |||
844 | // Uhh, we need to finish this before we enable it.. because it's blocking all sorts of goodies and features |
||
845 | if (IsAdministrator(user)) |
||
846 | permission = true; |
||
847 | |||
848 | if (IsEstateManager(user)) |
||
849 | permission = true; |
||
850 | |||
851 | if (!permission) |
||
852 | SendPermissionError(user, reason); |
||
853 | |||
854 | return permission; |
||
855 | } |
||
856 | |||
857 | public bool GenericEstatePermission(UUID user) |
||
858 | { |
||
859 | // Default: deny |
||
860 | bool permission = false; |
||
861 | |||
862 | // Estate admins should be able to use estate tools |
||
863 | if (IsEstateManager(user)) |
||
864 | permission = true; |
||
865 | |||
866 | // Administrators always have permission |
||
867 | if (IsAdministrator(user)) |
||
868 | permission = true; |
||
869 | |||
870 | return permission; |
||
871 | } |
||
872 | |||
873 | protected bool GenericParcelPermission(UUID user, ILandObject parcel, ulong groupPowers) |
||
874 | { |
||
875 | bool permission = false; |
||
876 | |||
877 | if (parcel.LandData.OwnerID == user) |
||
878 | { |
||
879 | permission = true; |
||
880 | } |
||
881 | |||
882 | if ((parcel.LandData.GroupID != UUID.Zero) && IsGroupMember(parcel.LandData.GroupID, user, groupPowers)) |
||
883 | { |
||
884 | permission = true; |
||
885 | } |
||
886 | |||
887 | if (IsEstateManager(user)) |
||
888 | { |
||
889 | permission = true; |
||
890 | } |
||
891 | |||
892 | if (IsAdministrator(user)) |
||
893 | { |
||
894 | permission = true; |
||
895 | } |
||
896 | |||
897 | if (m_SimpleBuildPermissions && |
||
898 | (parcel.LandData.Flags & (uint)ParcelFlags.UseAccessList) == 0 && parcel.IsInLandAccessList(user)) |
||
899 | permission = true; |
||
900 | |||
901 | return permission; |
||
902 | } |
||
903 | |||
904 | protected bool GenericParcelOwnerPermission(UUID user, ILandObject parcel, ulong groupPowers, bool allowEstateManager) |
||
905 | { |
||
906 | if (parcel.LandData.OwnerID == user) |
||
907 | { |
||
908 | // Returning immediately so that group deeded objects on group deeded land don't trigger a NRE on |
||
909 | // the subsequent redundant checks when using lParcelMediaCommandList() |
||
910 | // See http://opensimulator.org/mantis/view.php?id=3999 for more details |
||
911 | return true; |
||
912 | } |
||
913 | |||
914 | if (parcel.LandData.IsGroupOwned && IsGroupMember(parcel.LandData.GroupID, user, groupPowers)) |
||
915 | { |
||
916 | return true; |
||
917 | } |
||
918 | |||
919 | if (allowEstateManager && IsEstateManager(user)) |
||
920 | { |
||
921 | return true; |
||
922 | } |
||
923 | |||
924 | if (IsAdministrator(user)) |
||
925 | { |
||
926 | return true; |
||
927 | } |
||
928 | |||
929 | return false; |
||
930 | } |
||
931 | |||
932 | protected bool GenericParcelPermission(UUID user, Vector3 pos, ulong groupPowers) |
||
933 | { |
||
934 | ILandObject parcel = m_scene.LandChannel.GetLandObject(pos.X, pos.Y); |
||
935 | if (parcel == null) return false; |
||
936 | return GenericParcelPermission(user, parcel, groupPowers); |
||
937 | } |
||
938 | #endregion |
||
939 | |||
940 | #region Permission Checks |
||
941 | private bool CanAbandonParcel(UUID user, ILandObject parcel, Scene scene) |
||
942 | { |
||
943 | DebugPermissionInformation(MethodInfo.GetCurrentMethod().Name); |
||
944 | if (m_bypassPermissions) return m_bypassPermissionsValue; |
||
945 | |||
946 | return GenericParcelOwnerPermission(user, parcel, (ulong)GroupPowers.LandRelease, false); |
||
947 | } |
||
948 | |||
949 | private bool CanReclaimParcel(UUID user, ILandObject parcel, Scene scene) |
||
950 | { |
||
951 | DebugPermissionInformation(MethodInfo.GetCurrentMethod().Name); |
||
952 | if (m_bypassPermissions) return m_bypassPermissionsValue; |
||
953 | |||
954 | return GenericParcelOwnerPermission(user, parcel, 0,true); |
||
955 | } |
||
956 | |||
957 | private bool CanDeedParcel(UUID user, ILandObject parcel, Scene scene) |
||
958 | { |
||
959 | DebugPermissionInformation(MethodInfo.GetCurrentMethod().Name); |
||
960 | if (m_bypassPermissions) return m_bypassPermissionsValue; |
||
961 | |||
962 | if (parcel.LandData.OwnerID != user) // Only the owner can deed! |
||
963 | return false; |
||
964 | |||
965 | ScenePresence sp = scene.GetScenePresence(user); |
||
966 | IClientAPI client = sp.ControllingClient; |
||
967 | |||
968 | if ((client.GetGroupPowers(parcel.LandData.GroupID) & (ulong)GroupPowers.LandDeed) == 0) |
||
969 | return false; |
||
970 | |||
971 | return GenericParcelOwnerPermission(user, parcel, (ulong)GroupPowers.LandDeed, false); |
||
972 | } |
||
973 | |||
974 | private bool CanDeedObject(UUID user, UUID group, Scene scene) |
||
975 | { |
||
976 | DebugPermissionInformation(MethodInfo.GetCurrentMethod().Name); |
||
977 | if (m_bypassPermissions) return m_bypassPermissionsValue; |
||
978 | |||
979 | ScenePresence sp = scene.GetScenePresence(user); |
||
980 | IClientAPI client = sp.ControllingClient; |
||
981 | |||
982 | if ((client.GetGroupPowers(group) & (ulong)GroupPowers.DeedObject) == 0) |
||
983 | return false; |
||
984 | |||
985 | return true; |
||
986 | } |
||
987 | |||
988 | private bool IsGod(UUID user, Scene scene) |
||
989 | { |
||
990 | DebugPermissionInformation(MethodInfo.GetCurrentMethod().Name); |
||
991 | if (m_bypassPermissions) return m_bypassPermissionsValue; |
||
992 | |||
993 | return IsAdministrator(user); |
||
994 | } |
||
995 | |||
996 | private bool CanDuplicateObject(int objectCount, UUID objectID, UUID owner, Scene scene, Vector3 objectPosition) |
||
997 | { |
||
998 | DebugPermissionInformation(MethodInfo.GetCurrentMethod().Name); |
||
999 | if (m_bypassPermissions) return m_bypassPermissionsValue; |
||
1000 | |||
1001 | if (!GenericObjectPermission(owner, objectID, true)) |
||
1002 | { |
||
1003 | //They can't even edit the object |
||
1004 | return false; |
||
1005 | } |
||
1006 | |||
1007 | SceneObjectPart part = scene.GetSceneObjectPart(objectID); |
||
1008 | if (part == null) |
||
1009 | return false; |
||
1010 | |||
1011 | if (part.OwnerID == owner) |
||
1012 | { |
||
1013 | if ((part.OwnerMask & PERM_COPY) == 0) |
||
1014 | return false; |
||
1015 | } |
||
1016 | else if (part.GroupID != UUID.Zero) |
||
1017 | { |
||
1018 | if ((part.OwnerID == part.GroupID) && ((owner != part.LastOwnerID) || ((part.GroupMask & PERM_TRANS) == 0))) |
||
1019 | return false; |
||
1020 | |||
1021 | if ((part.GroupMask & PERM_COPY) == 0) |
||
1022 | return false; |
||
1023 | } |
||
1024 | |||
1025 | //If they can rez, they can duplicate |
||
1026 | return CanRezObject(objectCount, owner, objectPosition, scene); |
||
1027 | } |
||
1028 | |||
1029 | private bool CanDeleteObject(UUID objectID, UUID deleter, Scene scene) |
||
1030 | { |
||
1031 | DebugPermissionInformation(MethodInfo.GetCurrentMethod().Name); |
||
1032 | if (m_bypassPermissions) return m_bypassPermissionsValue; |
||
1033 | |||
1034 | return GenericObjectPermission(deleter, objectID, false); |
||
1035 | } |
||
1036 | |||
1037 | private bool CanEditObject(UUID objectID, UUID editorID, Scene scene) |
||
1038 | { |
||
1039 | DebugPermissionInformation(MethodInfo.GetCurrentMethod().Name); |
||
1040 | if (m_bypassPermissions) return m_bypassPermissionsValue; |
||
1041 | |||
1042 | return GenericObjectPermission(editorID, objectID, false); |
||
1043 | } |
||
1044 | |||
1045 | private bool CanEditObjectInventory(UUID objectID, UUID editorID, Scene scene) |
||
1046 | { |
||
1047 | DebugPermissionInformation(MethodInfo.GetCurrentMethod().Name); |
||
1048 | if (m_bypassPermissions) return m_bypassPermissionsValue; |
||
1049 | |||
1050 | return GenericObjectPermission(editorID, objectID, false); |
||
1051 | } |
||
1052 | |||
1053 | private bool CanEditParcelProperties(UUID user, ILandObject parcel, GroupPowers p, Scene scene) |
||
1054 | { |
||
1055 | DebugPermissionInformation(MethodInfo.GetCurrentMethod().Name); |
||
1056 | if (m_bypassPermissions) return m_bypassPermissionsValue; |
||
1057 | |||
1058 | return GenericParcelOwnerPermission(user, parcel, (ulong)p, false); |
||
1059 | } |
||
1060 | |||
1061 | /// <summary> |
||
1062 | /// Check whether the specified user can edit the given script |
||
1063 | /// </summary> |
||
1064 | /// <param name="script"></param> |
||
1065 | /// <param name="objectID"></param> |
||
1066 | /// <param name="user"></param> |
||
1067 | /// <param name="scene"></param> |
||
1068 | /// <returns></returns> |
||
1069 | private bool CanEditScript(UUID script, UUID objectID, UUID user, Scene scene) |
||
1070 | { |
||
1071 | DebugPermissionInformation(MethodInfo.GetCurrentMethod().Name); |
||
1072 | if (m_bypassPermissions) return m_bypassPermissionsValue; |
||
1073 | |||
1074 | if (m_allowedScriptEditors == UserSet.Administrators && !IsAdministrator(user)) |
||
1075 | return false; |
||
1076 | |||
1077 | // Ordinarily, if you can view it, you can edit it |
||
1078 | // There is no viewing a no mod script |
||
1079 | // |
||
1080 | return CanViewScript(script, objectID, user, scene); |
||
1081 | } |
||
1082 | |||
1083 | /// <summary> |
||
1084 | /// Check whether the specified user can edit the given notecard |
||
1085 | /// </summary> |
||
1086 | /// <param name="notecard"></param> |
||
1087 | /// <param name="objectID"></param> |
||
1088 | /// <param name="user"></param> |
||
1089 | /// <param name="scene"></param> |
||
1090 | /// <returns></returns> |
||
1091 | private bool CanEditNotecard(UUID notecard, UUID objectID, UUID user, Scene scene) |
||
1092 | { |
||
1093 | DebugPermissionInformation(MethodInfo.GetCurrentMethod().Name); |
||
1094 | if (m_bypassPermissions) return m_bypassPermissionsValue; |
||
1095 | |||
1096 | if (objectID == UUID.Zero) // User inventory |
||
1097 | { |
||
1098 | IInventoryService invService = m_scene.InventoryService; |
||
1099 | InventoryItemBase assetRequestItem = new InventoryItemBase(notecard, user); |
||
1100 | assetRequestItem = invService.GetItem(assetRequestItem); |
||
1101 | if (assetRequestItem == null && LibraryRootFolder != null) // Library item |
||
1102 | { |
||
1103 | assetRequestItem = LibraryRootFolder.FindItem(notecard); |
||
1104 | |||
1105 | if (assetRequestItem != null) // Implicitly readable |
||
1106 | return true; |
||
1107 | } |
||
1108 | |||
1109 | // Notecards must be both mod and copy to be saveable |
||
1110 | // This is because of they're not copy, you can't read |
||
1111 | // them, and if they're not mod, well, then they're |
||
1112 | // not mod. Duh. |
||
1113 | // |
||
1114 | if ((assetRequestItem.CurrentPermissions & |
||
1115 | ((uint)PermissionMask.Modify | |
||
1116 | (uint)PermissionMask.Copy)) != |
||
1117 | ((uint)PermissionMask.Modify | |
||
1118 | (uint)PermissionMask.Copy)) |
||
1119 | return false; |
||
1120 | } |
||
1121 | else // Prim inventory |
||
1122 | { |
||
1123 | SceneObjectPart part = scene.GetSceneObjectPart(objectID); |
||
1124 | |||
1125 | if (part == null) |
||
1126 | return false; |
||
1127 | |||
1128 | if (part.OwnerID != user) |
||
1129 | { |
||
1130 | if (part.GroupID == UUID.Zero) |
||
1131 | return false; |
||
1132 | |||
1133 | if (!IsGroupMember(part.GroupID, user, 0)) |
||
1134 | return false; |
||
1135 | |||
1136 | if ((part.GroupMask & (uint)PermissionMask.Modify) == 0) |
||
1137 | return false; |
||
1138 | } |
||
1139 | else |
||
1140 | { |
||
1141 | if ((part.OwnerMask & (uint)PermissionMask.Modify) == 0) |
||
1142 | return false; |
||
1143 | } |
||
1144 | |||
1145 | TaskInventoryItem ti = part.Inventory.GetInventoryItem(notecard); |
||
1146 | |||
1147 | if (ti == null) |
||
1148 | return false; |
||
1149 | |||
1150 | if (ti.OwnerID != user) |
||
1151 | { |
||
1152 | if (ti.GroupID == UUID.Zero) |
||
1153 | return false; |
||
1154 | |||
1155 | if (!IsGroupMember(ti.GroupID, user, 0)) |
||
1156 | return false; |
||
1157 | } |
||
1158 | |||
1159 | // Require full perms |
||
1160 | if ((ti.CurrentPermissions & |
||
1161 | ((uint)PermissionMask.Modify | |
||
1162 | (uint)PermissionMask.Copy)) != |
||
1163 | ((uint)PermissionMask.Modify | |
||
1164 | (uint)PermissionMask.Copy)) |
||
1165 | return false; |
||
1166 | } |
||
1167 | |||
1168 | return true; |
||
1169 | } |
||
1170 | |||
1171 | private bool CanInstantMessage(UUID user, UUID target, Scene startScene) |
||
1172 | { |
||
1173 | DebugPermissionInformation(MethodInfo.GetCurrentMethod().Name); |
||
1174 | if (m_bypassPermissions) return m_bypassPermissionsValue; |
||
1175 | |||
1176 | // If the sender is an object, check owner instead |
||
1177 | // |
||
1178 | SceneObjectPart part = startScene.GetSceneObjectPart(user); |
||
1179 | if (part != null) |
||
1180 | user = part.OwnerID; |
||
1181 | |||
1182 | return GenericCommunicationPermission(user, target); |
||
1183 | } |
||
1184 | |||
1185 | private bool CanInventoryTransfer(UUID user, UUID target, Scene startScene) |
||
1186 | { |
||
1187 | DebugPermissionInformation(MethodInfo.GetCurrentMethod().Name); |
||
1188 | if (m_bypassPermissions) return m_bypassPermissionsValue; |
||
1189 | |||
1190 | return GenericCommunicationPermission(user, target); |
||
1191 | } |
||
1192 | |||
1193 | private bool CanIssueEstateCommand(UUID user, Scene requestFromScene, bool ownerCommand) |
||
1194 | { |
||
1195 | DebugPermissionInformation(MethodInfo.GetCurrentMethod().Name); |
||
1196 | if (m_bypassPermissions) return m_bypassPermissionsValue; |
||
1197 | |||
1198 | if (IsAdministrator(user)) |
||
1199 | return true; |
||
1200 | |||
1201 | if (m_scene.RegionInfo.EstateSettings.IsEstateOwner(user)) |
||
1202 | return true; |
||
1203 | |||
1204 | if (ownerCommand) |
||
1205 | return false; |
||
1206 | |||
1207 | return GenericEstatePermission(user); |
||
1208 | } |
||
1209 | |||
1210 | private bool CanMoveObject(UUID objectID, UUID moverID, Scene scene) |
||
1211 | { |
||
1212 | DebugPermissionInformation(MethodInfo.GetCurrentMethod().Name); |
||
1213 | if (m_bypassPermissions) |
||
1214 | { |
||
1215 | SceneObjectPart part = scene.GetSceneObjectPart(objectID); |
||
1216 | if (part.OwnerID != moverID) |
||
1217 | { |
||
1218 | if (!part.ParentGroup.IsDeleted) |
||
1219 | { |
||
1220 | if (part.ParentGroup.IsAttachment) |
||
1221 | return false; |
||
1222 | } |
||
1223 | } |
||
1224 | return m_bypassPermissionsValue; |
||
1225 | } |
||
1226 | |||
1227 | bool permission = GenericObjectPermission(moverID, objectID, true); |
||
1228 | if (!permission) |
||
1229 | { |
||
1230 | if (!m_scene.Entities.ContainsKey(objectID)) |
||
1231 | { |
||
1232 | return false; |
||
1233 | } |
||
1234 | |||
1235 | // The client |
||
1236 | // may request to edit linked parts, and therefore, it needs |
||
1237 | // to also check for SceneObjectPart |
||
1238 | |||
1239 | // If it's not an object, we cant edit it. |
||
1240 | if ((!(m_scene.Entities[objectID] is SceneObjectGroup))) |
||
1241 | { |
||
1242 | return false; |
||
1243 | } |
||
1244 | |||
1245 | |||
1246 | SceneObjectGroup task = (SceneObjectGroup)m_scene.Entities[objectID]; |
||
1247 | |||
1248 | |||
1249 | // UUID taskOwner = null; |
||
1250 | // Added this because at this point in time it wouldn't be wise for |
||
1251 | // the administrator object permissions to take effect. |
||
1252 | // UUID objectOwner = task.OwnerID; |
||
1253 | |||
1254 | // Anyone can move |
||
1255 | if ((task.RootPart.EveryoneMask & PERM_MOVE) != 0) |
||
1256 | permission = true; |
||
1257 | |||
1258 | // Locked |
||
1259 | if ((task.RootPart.OwnerMask & PERM_LOCKED) == 0) |
||
1260 | permission = false; |
||
1261 | } |
||
1262 | else |
||
1263 | { |
||
1264 | bool locked = false; |
||
1265 | if (!m_scene.Entities.ContainsKey(objectID)) |
||
1266 | { |
||
1267 | return false; |
||
1268 | } |
||
1269 | |||
1270 | // If it's not an object, we cant edit it. |
||
1271 | if ((!(m_scene.Entities[objectID] is SceneObjectGroup))) |
||
1272 | { |
||
1273 | return false; |
||
1274 | } |
||
1275 | |||
1276 | SceneObjectGroup group = (SceneObjectGroup)m_scene.Entities[objectID]; |
||
1277 | |||
1278 | UUID objectOwner = group.OwnerID; |
||
1279 | locked = ((group.RootPart.OwnerMask & PERM_LOCKED) == 0); |
||
1280 | |||
1281 | // This is an exception to the generic object permission. |
||
1282 | // Administrators who lock their objects should not be able to move them, |
||
1283 | // however generic object permission should return true. |
||
1284 | // This keeps locked objects from being affected by random click + drag actions by accident |
||
1285 | // and allows the administrator to grab or delete a locked object. |
||
1286 | |||
1287 | // Administrators and estate managers are still able to click+grab locked objects not |
||
1288 | // owned by them in the scene |
||
1289 | // This is by design. |
||
1290 | |||
1291 | if (locked && (moverID == objectOwner)) |
||
1292 | return false; |
||
1293 | } |
||
1294 | return permission; |
||
1295 | } |
||
1296 | |||
1297 | private bool CanObjectEntry(UUID objectID, bool enteringRegion, Vector3 newPoint, Scene scene) |
||
1298 | { |
||
1299 | DebugPermissionInformation(MethodInfo.GetCurrentMethod().Name); |
||
1300 | if (m_bypassPermissions) return m_bypassPermissionsValue; |
||
1301 | |||
1302 | if ((newPoint.X > 257f || newPoint.X < -1f || newPoint.Y > 257f || newPoint.Y < -1f)) |
||
1303 | { |
||
1304 | return true; |
||
1305 | } |
||
1306 | |||
1307 | SceneObjectGroup task = (SceneObjectGroup)m_scene.Entities[objectID]; |
||
1308 | |||
1309 | ILandObject land = m_scene.LandChannel.GetLandObject(newPoint.X, newPoint.Y); |
||
1310 | |||
1311 | if (!enteringRegion) |
||
1312 | { |
||
1313 | ILandObject fromland = m_scene.LandChannel.GetLandObject(task.AbsolutePosition.X, task.AbsolutePosition.Y); |
||
1314 | |||
1315 | if (fromland == land) // Not entering |
||
1316 | return true; |
||
1317 | } |
||
1318 | |||
1319 | if (land == null) |
||
1320 | { |
||
1321 | return false; |
||
1322 | } |
||
1323 | |||
1324 | if ((land.LandData.Flags & ((int)ParcelFlags.AllowAPrimitiveEntry)) != 0) |
||
1325 | { |
||
1326 | return true; |
||
1327 | } |
||
1328 | |||
1329 | if (!m_scene.Entities.ContainsKey(objectID)) |
||
1330 | { |
||
1331 | return false; |
||
1332 | } |
||
1333 | |||
1334 | // If it's not an object, we cant edit it. |
||
1335 | if (!(m_scene.Entities[objectID] is SceneObjectGroup)) |
||
1336 | { |
||
1337 | return false; |
||
1338 | } |
||
1339 | |||
1340 | |||
1341 | if (GenericParcelPermission(task.OwnerID, newPoint, 0)) |
||
1342 | { |
||
1343 | return true; |
||
1344 | } |
||
1345 | |||
1346 | //Otherwise, false! |
||
1347 | return false; |
||
1348 | } |
||
1349 | |||
1350 | private bool CanReturnObjects(ILandObject land, UUID user, List<SceneObjectGroup> objects, Scene scene) |
||
1351 | { |
||
1352 | DebugPermissionInformation(MethodInfo.GetCurrentMethod().Name); |
||
1353 | if (m_bypassPermissions) return m_bypassPermissionsValue; |
||
1354 | |||
1355 | GroupPowers powers; |
||
1356 | ILandObject l; |
||
1357 | |||
1358 | ScenePresence sp = scene.GetScenePresence(user); |
||
1359 | if (sp == null) |
||
1360 | return false; |
||
1361 | |||
1362 | IClientAPI client = sp.ControllingClient; |
||
1363 | |||
1364 | foreach (SceneObjectGroup g in new List<SceneObjectGroup>(objects)) |
||
1365 | { |
||
1366 | // Any user can return their own objects at any time |
||
1367 | // |
||
1368 | if (GenericObjectPermission(user, g.UUID, false)) |
||
1369 | continue; |
||
1370 | |||
1371 | // This is a short cut for efficiency. If land is non-null, |
||
1372 | // then all objects are on that parcel and we can save |
||
1373 | // ourselves the checking for each prim. Much faster. |
||
1374 | // |
||
1375 | if (land != null) |
||
1376 | { |
||
1377 | l = land; |
||
1378 | } |
||
1379 | else |
||
1380 | { |
||
1381 | Vector3 pos = g.AbsolutePosition; |
||
1382 | |||
1383 | l = scene.LandChannel.GetLandObject(pos.X, pos.Y); |
||
1384 | } |
||
1385 | |||
1386 | // If it's not over any land, then we can't do a thing |
||
1387 | if (l == null) |
||
1388 | { |
||
1389 | objects.Remove(g); |
||
1390 | continue; |
||
1391 | } |
||
1392 | |||
1393 | // If we own the land outright, then allow |
||
1394 | // |
||
1395 | if (l.LandData.OwnerID == user) |
||
1396 | continue; |
||
1397 | |||
1398 | // Group voodoo |
||
1399 | // |
||
1400 | if (l.LandData.IsGroupOwned) |
||
1401 | { |
||
1402 | powers = (GroupPowers)client.GetGroupPowers(l.LandData.GroupID); |
||
1403 | // Not a group member, or no rights at all |
||
1404 | // |
||
1405 | if (powers == (GroupPowers)0) |
||
1406 | { |
||
1407 | objects.Remove(g); |
||
1408 | continue; |
||
1409 | } |
||
1410 | |||
1411 | // Group deeded object? |
||
1412 | // |
||
1413 | if (g.OwnerID == l.LandData.GroupID && |
||
1414 | (powers & GroupPowers.ReturnGroupOwned) == (GroupPowers)0) |
||
1415 | { |
||
1416 | objects.Remove(g); |
||
1417 | continue; |
||
1418 | } |
||
1419 | |||
1420 | // Group set object? |
||
1421 | // |
||
1422 | if (g.GroupID == l.LandData.GroupID && |
||
1423 | (powers & GroupPowers.ReturnGroupSet) == (GroupPowers)0) |
||
1424 | { |
||
1425 | objects.Remove(g); |
||
1426 | continue; |
||
1427 | } |
||
1428 | |||
1429 | if ((powers & GroupPowers.ReturnNonGroup) == (GroupPowers)0) |
||
1430 | { |
||
1431 | objects.Remove(g); |
||
1432 | continue; |
||
1433 | } |
||
1434 | |||
1435 | // So we can remove all objects from this group land. |
||
1436 | // Fine. |
||
1437 | // |
||
1438 | continue; |
||
1439 | } |
||
1440 | |||
1441 | // By default, we can't remove |
||
1442 | // |
||
1443 | objects.Remove(g); |
||
1444 | } |
||
1445 | |||
1446 | if (objects.Count == 0) |
||
1447 | return false; |
||
1448 | |||
1449 | return true; |
||
1450 | } |
||
1451 | |||
1452 | private bool CanRezObject(int objectCount, UUID owner, Vector3 objectPosition, Scene scene) |
||
1453 | { |
||
1454 | DebugPermissionInformation(MethodInfo.GetCurrentMethod().Name); |
||
1455 | if (m_bypassPermissions) return m_bypassPermissionsValue; |
||
1456 | |||
1457 | // m_log.DebugFormat("[PERMISSIONS MODULE]: Checking rez object at {0} in {1}", objectPosition, m_scene.Name); |
||
1458 | |||
1459 | ILandObject parcel = m_scene.LandChannel.GetLandObject(objectPosition.X, objectPosition.Y); |
||
1460 | if (parcel == null) |
||
1461 | return false; |
||
1462 | |||
1463 | if ((parcel.LandData.Flags & (uint)ParcelFlags.CreateObjects) != 0) |
||
1464 | { |
||
1465 | return true; |
||
1466 | } |
||
1467 | else if ((owner == parcel.LandData.OwnerID) || IsAdministrator(owner)) |
||
1468 | { |
||
1469 | return true; |
||
1470 | } |
||
1471 | else if (((parcel.LandData.Flags & (uint)ParcelFlags.CreateGroupObjects) != 0) |
||
1472 | && (parcel.LandData.GroupID != UUID.Zero) && IsGroupMember(parcel.LandData.GroupID, owner, 0)) |
||
1473 | { |
||
1474 | return true; |
||
1475 | } |
||
1476 | else if (parcel.LandData.GroupID != UUID.Zero && IsGroupMember(parcel.LandData.GroupID, owner, (ulong)GroupPowers.AllowRez)) |
||
1477 | { |
||
1478 | return true; |
||
1479 | } |
||
1480 | else |
||
1481 | { |
||
1482 | return false; |
||
1483 | } |
||
1484 | } |
||
1485 | |||
1486 | private bool CanRunConsoleCommand(UUID user, Scene requestFromScene) |
||
1487 | { |
||
1488 | DebugPermissionInformation(MethodInfo.GetCurrentMethod().Name); |
||
1489 | if (m_bypassPermissions) return m_bypassPermissionsValue; |
||
1490 | |||
1491 | |||
1492 | return IsAdministrator(user); |
||
1493 | } |
||
1494 | |||
1495 | private bool CanRunScript(UUID script, UUID objectID, UUID user, Scene scene) |
||
1496 | { |
||
1497 | DebugPermissionInformation(MethodInfo.GetCurrentMethod().Name); |
||
1498 | if (m_bypassPermissions) return m_bypassPermissionsValue; |
||
1499 | |||
1500 | return true; |
||
1501 | } |
||
1502 | |||
1503 | private bool CanSellParcel(UUID user, ILandObject parcel, Scene scene) |
||
1504 | { |
||
1505 | DebugPermissionInformation(MethodInfo.GetCurrentMethod().Name); |
||
1506 | if (m_bypassPermissions) return m_bypassPermissionsValue; |
||
1507 | |||
1508 | return GenericParcelOwnerPermission(user, parcel, (ulong)GroupPowers.LandSetSale, false); |
||
1509 | } |
||
1510 | |||
1511 | private bool CanTakeObject(UUID objectID, UUID stealer, Scene scene) |
||
1512 | { |
||
1513 | DebugPermissionInformation(MethodInfo.GetCurrentMethod().Name); |
||
1514 | if (m_bypassPermissions) return m_bypassPermissionsValue; |
||
1515 | |||
1516 | return GenericObjectPermission(stealer,objectID, false); |
||
1517 | } |
||
1518 | |||
1519 | private bool CanTakeCopyObject(UUID objectID, UUID userID, Scene inScene) |
||
1520 | { |
||
1521 | DebugPermissionInformation(MethodInfo.GetCurrentMethod().Name); |
||
1522 | if (m_bypassPermissions) return m_bypassPermissionsValue; |
||
1523 | |||
1524 | bool permission = GenericObjectPermission(userID, objectID, false); |
||
1525 | if (!permission) |
||
1526 | { |
||
1527 | if (!m_scene.Entities.ContainsKey(objectID)) |
||
1528 | { |
||
1529 | return false; |
||
1530 | } |
||
1531 | |||
1532 | // If it's not an object, we cant edit it. |
||
1533 | if (!(m_scene.Entities[objectID] is SceneObjectGroup)) |
||
1534 | { |
||
1535 | return false; |
||
1536 | } |
||
1537 | |||
1538 | SceneObjectGroup task = (SceneObjectGroup)m_scene.Entities[objectID]; |
||
1539 | // UUID taskOwner = null; |
||
1540 | // Added this because at this point in time it wouldn't be wise for |
||
1541 | // the administrator object permissions to take effect. |
||
1542 | // UUID objectOwner = task.OwnerID; |
||
1543 | |||
1544 | if ((task.RootPart.EveryoneMask & PERM_COPY) != 0) |
||
1545 | permission = true; |
||
1546 | |||
1547 | if (task.OwnerID != userID) |
||
1548 | { |
||
1549 | if ((task.GetEffectivePermissions() & (PERM_COPY | PERM_TRANS)) != (PERM_COPY | PERM_TRANS)) |
||
1550 | permission = false; |
||
1551 | } |
||
1552 | else |
||
1553 | { |
||
1554 | if ((task.GetEffectivePermissions() & PERM_COPY) != PERM_COPY) |
||
1555 | permission = false; |
||
1556 | } |
||
1557 | } |
||
1558 | else |
||
1559 | { |
||
1560 | SceneObjectGroup task = (SceneObjectGroup)m_scene.Entities[objectID]; |
||
1561 | |||
1562 | if ((task.GetEffectivePermissions() & (PERM_COPY | PERM_TRANS)) != (PERM_COPY | PERM_TRANS)) |
||
1563 | permission = false; |
||
1564 | } |
||
1565 | |||
1566 | return permission; |
||
1567 | } |
||
1568 | |||
1569 | private bool CanTerraformLand(UUID user, Vector3 position, Scene requestFromScene) |
||
1570 | { |
||
1571 | DebugPermissionInformation(MethodInfo.GetCurrentMethod().Name); |
||
1572 | if (m_bypassPermissions) return m_bypassPermissionsValue; |
||
1573 | |||
1574 | // Estate override |
||
1575 | if (GenericEstatePermission(user)) |
||
1576 | return true; |
||
1577 | |||
1578 | float X = position.X; |
||
1579 | float Y = position.Y; |
||
1580 | |||
1581 | if (X > ((int)m_scene.RegionInfo.RegionSizeX - 1)) |
||
1582 | X = ((int)m_scene.RegionInfo.RegionSizeX - 1); |
||
1583 | if (Y > ((int)m_scene.RegionInfo.RegionSizeY - 1)) |
||
1584 | Y = ((int)m_scene.RegionInfo.RegionSizeY - 1); |
||
1585 | if (X < 0) |
||
1586 | X = 0; |
||
1587 | if (Y < 0) |
||
1588 | Y = 0; |
||
1589 | |||
1590 | ILandObject parcel = m_scene.LandChannel.GetLandObject(X, Y); |
||
1591 | if (parcel == null) |
||
1592 | return false; |
||
1593 | |||
1594 | // Others allowed to terraform? |
||
1595 | if ((parcel.LandData.Flags & ((int)ParcelFlags.AllowTerraform)) != 0) |
||
1596 | return true; |
||
1597 | |||
1598 | // Land owner can terraform too |
||
1599 | if (parcel != null && GenericParcelPermission(user, parcel, (ulong)GroupPowers.AllowEditLand)) |
||
1600 | return true; |
||
1601 | |||
1602 | return false; |
||
1603 | } |
||
1604 | |||
1605 | /// <summary> |
||
1606 | /// Check whether the specified user can view the given script |
||
1607 | /// </summary> |
||
1608 | /// <param name="script"></param> |
||
1609 | /// <param name="objectID"></param> |
||
1610 | /// <param name="user"></param> |
||
1611 | /// <param name="scene"></param> |
||
1612 | /// <returns></returns> |
||
1613 | private bool CanViewScript(UUID script, UUID objectID, UUID user, Scene scene) |
||
1614 | { |
||
1615 | DebugPermissionInformation(MethodInfo.GetCurrentMethod().Name); |
||
1616 | if (m_bypassPermissions) return m_bypassPermissionsValue; |
||
1617 | |||
1618 | if (objectID == UUID.Zero) // User inventory |
||
1619 | { |
||
1620 | IInventoryService invService = m_scene.InventoryService; |
||
1621 | InventoryItemBase assetRequestItem = new InventoryItemBase(script, user); |
||
1622 | assetRequestItem = invService.GetItem(assetRequestItem); |
||
1623 | if (assetRequestItem == null && LibraryRootFolder != null) // Library item |
||
1624 | { |
||
1625 | assetRequestItem = LibraryRootFolder.FindItem(script); |
||
1626 | |||
1627 | if (assetRequestItem != null) // Implicitly readable |
||
1628 | return true; |
||
1629 | } |
||
1630 | |||
1631 | // SL is rather harebrained here. In SL, a script you |
||
1632 | // have mod/copy no trans is readable. This subverts |
||
1633 | // permissions, but is used in some products, most |
||
1634 | // notably Hippo door plugin and HippoRent 5 networked |
||
1635 | // prim counter. |
||
1636 | // To enable this broken SL-ism, remove Transfer from |
||
1637 | // the below expressions. |
||
1638 | // Trying to improve on SL perms by making a script |
||
1639 | // readable only if it's really full perms |
||
1640 | // |
||
1641 | if ((assetRequestItem.CurrentPermissions & |
||
1642 | ((uint)PermissionMask.Modify | |
||
1643 | (uint)PermissionMask.Copy | |
||
1644 | (uint)PermissionMask.Transfer)) != |
||
1645 | ((uint)PermissionMask.Modify | |
||
1646 | (uint)PermissionMask.Copy | |
||
1647 | (uint)PermissionMask.Transfer)) |
||
1648 | return false; |
||
1649 | } |
||
1650 | else // Prim inventory |
||
1651 | { |
||
1652 | SceneObjectPart part = scene.GetSceneObjectPart(objectID); |
||
1653 | |||
1654 | if (part == null) |
||
1655 | return false; |
||
1656 | |||
1657 | if (part.OwnerID != user) |
||
1658 | { |
||
1659 | if (part.GroupID == UUID.Zero) |
||
1660 | return false; |
||
1661 | |||
1662 | if (!IsGroupMember(part.GroupID, user, 0)) |
||
1663 | return false; |
||
1664 | |||
1665 | if ((part.GroupMask & (uint)PermissionMask.Modify) == 0) |
||
1666 | return false; |
||
1667 | } |
||
1668 | else |
||
1669 | { |
||
1670 | if ((part.OwnerMask & (uint)PermissionMask.Modify) == 0) |
||
1671 | return false; |
||
1672 | } |
||
1673 | |||
1674 | TaskInventoryItem ti = part.Inventory.GetInventoryItem(script); |
||
1675 | |||
1676 | if (ti == null) |
||
1677 | return false; |
||
1678 | |||
1679 | if (ti.OwnerID != user) |
||
1680 | { |
||
1681 | if (ti.GroupID == UUID.Zero) |
||
1682 | return false; |
||
1683 | |||
1684 | if (!IsGroupMember(ti.GroupID, user, 0)) |
||
1685 | return false; |
||
1686 | } |
||
1687 | |||
1688 | // Require full perms |
||
1689 | if ((ti.CurrentPermissions & |
||
1690 | ((uint)PermissionMask.Modify | |
||
1691 | (uint)PermissionMask.Copy | |
||
1692 | (uint)PermissionMask.Transfer)) != |
||
1693 | ((uint)PermissionMask.Modify | |
||
1694 | (uint)PermissionMask.Copy | |
||
1695 | (uint)PermissionMask.Transfer)) |
||
1696 | return false; |
||
1697 | } |
||
1698 | |||
1699 | return true; |
||
1700 | } |
||
1701 | |||
1702 | /// <summary> |
||
1703 | /// Check whether the specified user can view the given notecard |
||
1704 | /// </summary> |
||
1705 | /// <param name="script"></param> |
||
1706 | /// <param name="objectID"></param> |
||
1707 | /// <param name="user"></param> |
||
1708 | /// <param name="scene"></param> |
||
1709 | /// <returns></returns> |
||
1710 | private bool CanViewNotecard(UUID notecard, UUID objectID, UUID user, Scene scene) |
||
1711 | { |
||
1712 | DebugPermissionInformation(MethodInfo.GetCurrentMethod().Name); |
||
1713 | if (m_bypassPermissions) return m_bypassPermissionsValue; |
||
1714 | |||
1715 | if (objectID == UUID.Zero) // User inventory |
||
1716 | { |
||
1717 | IInventoryService invService = m_scene.InventoryService; |
||
1718 | InventoryItemBase assetRequestItem = new InventoryItemBase(notecard, user); |
||
1719 | assetRequestItem = invService.GetItem(assetRequestItem); |
||
1720 | if (assetRequestItem == null && LibraryRootFolder != null) // Library item |
||
1721 | { |
||
1722 | assetRequestItem = LibraryRootFolder.FindItem(notecard); |
||
1723 | |||
1724 | if (assetRequestItem != null) // Implicitly readable |
||
1725 | return true; |
||
1726 | } |
||
1727 | |||
1728 | // Notecards are always readable unless no copy |
||
1729 | // |
||
1730 | if ((assetRequestItem.CurrentPermissions & |
||
1731 | (uint)PermissionMask.Copy) != |
||
1732 | (uint)PermissionMask.Copy) |
||
1733 | return false; |
||
1734 | } |
||
1735 | else // Prim inventory |
||
1736 | { |
||
1737 | SceneObjectPart part = scene.GetSceneObjectPart(objectID); |
||
1738 | |||
1739 | if (part == null) |
||
1740 | return false; |
||
1741 | |||
1742 | if (part.OwnerID != user) |
||
1743 | { |
||
1744 | if (part.GroupID == UUID.Zero) |
||
1745 | return false; |
||
1746 | |||
1747 | if (!IsGroupMember(part.GroupID, user, 0)) |
||
1748 | return false; |
||
1749 | } |
||
1750 | |||
1751 | if ((part.OwnerMask & (uint)PermissionMask.Modify) == 0) |
||
1752 | return false; |
||
1753 | |||
1754 | TaskInventoryItem ti = part.Inventory.GetInventoryItem(notecard); |
||
1755 | |||
1756 | if (ti == null) |
||
1757 | return false; |
||
1758 | |||
1759 | if (ti.OwnerID != user) |
||
1760 | { |
||
1761 | if (ti.GroupID == UUID.Zero) |
||
1762 | return false; |
||
1763 | |||
1764 | if (!IsGroupMember(ti.GroupID, user, 0)) |
||
1765 | return false; |
||
1766 | } |
||
1767 | |||
1768 | // Notecards are always readable unless no copy |
||
1769 | // |
||
1770 | if ((ti.CurrentPermissions & |
||
1771 | (uint)PermissionMask.Copy) != |
||
1772 | (uint)PermissionMask.Copy) |
||
1773 | return false; |
||
1774 | } |
||
1775 | |||
1776 | return true; |
||
1777 | } |
||
1778 | |||
1779 | #endregion |
||
1780 | |||
1781 | private bool CanLinkObject(UUID userID, UUID objectID) |
||
1782 | { |
||
1783 | DebugPermissionInformation(MethodInfo.GetCurrentMethod().Name); |
||
1784 | if (m_bypassPermissions) return m_bypassPermissionsValue; |
||
1785 | |||
1786 | return GenericObjectPermission(userID, objectID, false); |
||
1787 | } |
||
1788 | |||
1789 | private bool CanDelinkObject(UUID userID, UUID objectID) |
||
1790 | { |
||
1791 | DebugPermissionInformation(MethodInfo.GetCurrentMethod().Name); |
||
1792 | if (m_bypassPermissions) return m_bypassPermissionsValue; |
||
1793 | |||
1794 | return GenericObjectPermission(userID, objectID, false); |
||
1795 | } |
||
1796 | |||
1797 | private bool CanBuyLand(UUID userID, ILandObject parcel, Scene scene) |
||
1798 | { |
||
1799 | DebugPermissionInformation(MethodInfo.GetCurrentMethod().Name); |
||
1800 | if (m_bypassPermissions) return m_bypassPermissionsValue; |
||
1801 | |||
1802 | return true; |
||
1803 | } |
||
1804 | |||
1805 | private bool CanCopyObjectInventory(UUID itemID, UUID objectID, UUID userID) |
||
1806 | { |
||
1807 | DebugPermissionInformation(MethodInfo.GetCurrentMethod().Name); |
||
1808 | if (m_bypassPermissions) return m_bypassPermissionsValue; |
||
1809 | |||
1810 | return true; |
||
1811 | } |
||
1812 | |||
1813 | private bool CanDeleteObjectInventory(UUID itemID, UUID objectID, UUID userID) |
||
1814 | { |
||
1815 | DebugPermissionInformation(MethodInfo.GetCurrentMethod().Name); |
||
1816 | if (m_bypassPermissions) return m_bypassPermissionsValue; |
||
1817 | |||
1818 | return true; |
||
1819 | } |
||
1820 | |||
1821 | /// <summary> |
||
1822 | /// Check whether the specified user is allowed to directly create the given inventory type in a prim's |
||
1823 | /// inventory (e.g. the New Script button in the 1.21 Linden Lab client). |
||
1824 | /// </summary> |
||
1825 | /// <param name="invType"></param> |
||
1826 | /// <param name="objectID"></param> |
||
1827 | /// <param name="userID"></param> |
||
1828 | /// <returns></returns> |
||
1829 | private bool CanCreateObjectInventory(int invType, UUID objectID, UUID userID) |
||
1830 | { |
||
1831 | DebugPermissionInformation(MethodInfo.GetCurrentMethod().Name); |
||
1832 | if (m_bypassPermissions) return m_bypassPermissionsValue; |
||
1833 | |||
1834 | SceneObjectPart part = m_scene.GetSceneObjectPart(objectID); |
||
1835 | ScenePresence p = m_scene.GetScenePresence(userID); |
||
1836 | |||
1837 | if (part == null || p == null) |
||
1838 | return false; |
||
1839 | |||
1840 | if (!IsAdministrator(userID)) |
||
1841 | { |
||
1842 | if (part.OwnerID != userID) |
||
1843 | { |
||
1844 | // Group permissions |
||
1845 | if ((part.GroupID == UUID.Zero) || (p.ControllingClient.GetGroupPowers(part.GroupID) == 0) || ((part.GroupMask & (uint)PermissionMask.Modify) == 0)) |
||
1846 | return false; |
||
1847 | } else { |
||
1848 | if ((part.OwnerMask & (uint)PermissionMask.Modify) == 0) |
||
1849 | return false; |
||
1850 | } |
||
1851 | if ((int)InventoryType.LSL == invType) |
||
1852 | if (m_allowedScriptCreators == UserSet.Administrators) |
||
1853 | return false; |
||
1854 | } |
||
1855 | |||
1856 | return true; |
||
1857 | } |
||
1858 | |||
1859 | /// <summary> |
||
1860 | /// Check whether the specified user is allowed to create the given inventory type in their inventory. |
||
1861 | /// </summary> |
||
1862 | /// <param name="invType"></param> |
||
1863 | /// <param name="userID"></param> |
||
1864 | /// <returns></returns> |
||
1865 | private bool CanCreateUserInventory(int invType, UUID userID) |
||
1866 | { |
||
1867 | DebugPermissionInformation(MethodInfo.GetCurrentMethod().Name); |
||
1868 | if (m_bypassPermissions) return m_bypassPermissionsValue; |
||
1869 | |||
1870 | if ((int)InventoryType.LSL == invType) |
||
1871 | if (m_allowedScriptCreators == UserSet.Administrators && !IsAdministrator(userID)) |
||
1872 | return false; |
||
1873 | |||
1874 | return true; |
||
1875 | } |
||
1876 | |||
1877 | /// <summary> |
||
1878 | /// Check whether the specified user is allowed to copy the given inventory type in their inventory. |
||
1879 | /// </summary> |
||
1880 | /// <param name="itemID"></param> |
||
1881 | /// <param name="userID"></param> |
||
1882 | /// <returns></returns> |
||
1883 | private bool CanCopyUserInventory(UUID itemID, UUID userID) |
||
1884 | { |
||
1885 | DebugPermissionInformation(MethodInfo.GetCurrentMethod().Name); |
||
1886 | if (m_bypassPermissions) return m_bypassPermissionsValue; |
||
1887 | |||
1888 | return true; |
||
1889 | } |
||
1890 | |||
1891 | /// <summary> |
||
1892 | /// Check whether the specified user is allowed to edit the given inventory item within their own inventory. |
||
1893 | /// </summary> |
||
1894 | /// <param name="itemID"></param> |
||
1895 | /// <param name="userID"></param> |
||
1896 | /// <returns></returns> |
||
1897 | private bool CanEditUserInventory(UUID itemID, UUID userID) |
||
1898 | { |
||
1899 | DebugPermissionInformation(MethodInfo.GetCurrentMethod().Name); |
||
1900 | if (m_bypassPermissions) return m_bypassPermissionsValue; |
||
1901 | |||
1902 | return true; |
||
1903 | } |
||
1904 | |||
1905 | /// <summary> |
||
1906 | /// Check whether the specified user is allowed to delete the given inventory item from their own inventory. |
||
1907 | /// </summary> |
||
1908 | /// <param name="itemID"></param> |
||
1909 | /// <param name="userID"></param> |
||
1910 | /// <returns></returns> |
||
1911 | private bool CanDeleteUserInventory(UUID itemID, UUID userID) |
||
1912 | { |
||
1913 | DebugPermissionInformation(MethodInfo.GetCurrentMethod().Name); |
||
1914 | if (m_bypassPermissions) return m_bypassPermissionsValue; |
||
1915 | |||
1916 | return true; |
||
1917 | } |
||
1918 | |||
1919 | private bool CanTeleport(UUID userID, Scene scene) |
||
1920 | { |
||
1921 | DebugPermissionInformation(MethodInfo.GetCurrentMethod().Name); |
||
1922 | if (m_bypassPermissions) return m_bypassPermissionsValue; |
||
1923 | |||
1924 | return true; |
||
1925 | } |
||
1926 | |||
1927 | private bool CanResetScript(UUID prim, UUID script, UUID agentID, Scene scene) |
||
1928 | { |
||
1929 | DebugPermissionInformation(MethodInfo.GetCurrentMethod().Name); |
||
1930 | if (m_bypassPermissions) return m_bypassPermissionsValue; |
||
1931 | |||
1932 | SceneObjectPart part = m_scene.GetSceneObjectPart(prim); |
||
1933 | |||
1934 | // If we selected a sub-prim to reset, prim won't represent the object, but only a part. |
||
1935 | // We have to check the permissions of the object, though. |
||
1936 | if (part.ParentID != 0) prim = part.ParentUUID; |
||
1937 | |||
1938 | // You can reset the scripts in any object you can edit |
||
1939 | return GenericObjectPermission(agentID, prim, false); |
||
1940 | } |
||
1941 | |||
1942 | private bool CanCompileScript(UUID ownerUUID, int scriptType, Scene scene) |
||
1943 | { |
||
1944 | //m_log.DebugFormat("check if {0} is allowed to compile {1}", ownerUUID, scriptType); |
||
1945 | switch (scriptType) { |
||
1946 | case 0: |
||
1947 | if (GrantLSL.Count == 0 || GrantLSL.ContainsKey(ownerUUID.ToString())) { |
||
1948 | return(true); |
||
1949 | } |
||
1950 | break; |
||
1951 | case 1: |
||
1952 | if (GrantCS.Count == 0 || GrantCS.ContainsKey(ownerUUID.ToString())) { |
||
1953 | return(true); |
||
1954 | } |
||
1955 | break; |
||
1956 | case 2: |
||
1957 | if (GrantVB.Count == 0 || GrantVB.ContainsKey(ownerUUID.ToString())) { |
||
1958 | return(true); |
||
1959 | } |
||
1960 | break; |
||
1961 | case 3: |
||
1962 | if (GrantJS.Count == 0 || GrantJS.ContainsKey(ownerUUID.ToString())) |
||
1963 | { |
||
1964 | return (true); |
||
1965 | } |
||
1966 | break; |
||
1967 | case 4: |
||
1968 | if (GrantYP.Count == 0 || GrantYP.ContainsKey(ownerUUID.ToString())) |
||
1969 | { |
||
1970 | return (true); |
||
1971 | } |
||
1972 | break; |
||
1973 | } |
||
1974 | return(false); |
||
1975 | } |
||
1976 | |||
1977 | private bool CanControlPrimMedia(UUID agentID, UUID primID, int face) |
||
1978 | { |
||
1979 | // m_log.DebugFormat( |
||
1980 | // "[PERMISSONS]: Performing CanControlPrimMedia check with agentID {0}, primID {1}, face {2}", |
||
1981 | // agentID, primID, face); |
||
1982 | |||
1983 | if (null == MoapModule) |
||
1984 | return false; |
||
1985 | |||
1986 | SceneObjectPart part = m_scene.GetSceneObjectPart(primID); |
||
1987 | if (null == part) |
||
1988 | return false; |
||
1989 | |||
1990 | MediaEntry me = MoapModule.GetMediaEntry(part, face); |
||
1991 | |||
1992 | // If there is no existing media entry then it can be controlled (in this context, created). |
||
1993 | if (null == me) |
||
1994 | return true; |
||
1995 | |||
1996 | // m_log.DebugFormat( |
||
1997 | // "[PERMISSIONS]: Checking CanControlPrimMedia for {0} on {1} face {2} with control permissions {3}", |
||
1998 | // agentID, primID, face, me.ControlPermissions); |
||
1999 | |||
2000 | return GenericObjectPermission(agentID, part.ParentGroup.UUID, true); |
||
2001 | } |
||
2002 | |||
2003 | private bool CanInteractWithPrimMedia(UUID agentID, UUID primID, int face) |
||
2004 | { |
||
2005 | // m_log.DebugFormat( |
||
2006 | // "[PERMISSONS]: Performing CanInteractWithPrimMedia check with agentID {0}, primID {1}, face {2}", |
||
2007 | // agentID, primID, face); |
||
2008 | |||
2009 | if (null == MoapModule) |
||
2010 | return false; |
||
2011 | |||
2012 | SceneObjectPart part = m_scene.GetSceneObjectPart(primID); |
||
2013 | if (null == part) |
||
2014 | return false; |
||
2015 | |||
2016 | MediaEntry me = MoapModule.GetMediaEntry(part, face); |
||
2017 | |||
2018 | // If there is no existing media entry then it can be controlled (in this context, created). |
||
2019 | if (null == me) |
||
2020 | return true; |
||
2021 | |||
2022 | // m_log.DebugFormat( |
||
2023 | // "[PERMISSIONS]: Checking CanInteractWithPrimMedia for {0} on {1} face {2} with interact permissions {3}", |
||
2024 | // agentID, primID, face, me.InteractPermissions); |
||
2025 | |||
2026 | return GenericPrimMediaPermission(part, agentID, me.InteractPermissions); |
||
2027 | } |
||
2028 | |||
2029 | private bool GenericPrimMediaPermission(SceneObjectPart part, UUID agentID, MediaPermission perms) |
||
2030 | { |
||
2031 | // if (IsAdministrator(agentID)) |
||
2032 | // return true; |
||
2033 | |||
2034 | if ((perms & MediaPermission.Anyone) == MediaPermission.Anyone) |
||
2035 | return true; |
||
2036 | |||
2037 | if ((perms & MediaPermission.Owner) == MediaPermission.Owner) |
||
2038 | { |
||
2039 | if (agentID == part.OwnerID) |
||
2040 | return true; |
||
2041 | } |
||
2042 | |||
2043 | if ((perms & MediaPermission.Group) == MediaPermission.Group) |
||
2044 | { |
||
2045 | if (IsGroupMember(part.GroupID, agentID, 0)) |
||
2046 | return true; |
||
2047 | } |
||
2048 | |||
2049 | return false; |
||
2050 | } |
||
2051 | } |
||
2052 | } |