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