clockwerk-opensim – Blame information for rev 1

Subversion Repositories:
Rev:
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 }