aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Environment/Modules/World/Permissions
diff options
context:
space:
mode:
authorJustin Clarke Casey2008-05-05 20:14:53 +0000
committerJustin Clarke Casey2008-05-05 20:14:53 +0000
commit9655cf280779021e6241a08f8610cad9b982763f (patch)
tree82ef6d74969e4b64971d64a6a18e4488729167a8 /OpenSim/Region/Environment/Modules/World/Permissions
parent* Just some tidy up and documentation before I make my first ever attempt to ... (diff)
downloadopensim-SC-9655cf280779021e6241a08f8610cad9b982763f.zip
opensim-SC-9655cf280779021e6241a08f8610cad9b982763f.tar.gz
opensim-SC-9655cf280779021e6241a08f8610cad9b982763f.tar.bz2
opensim-SC-9655cf280779021e6241a08f8610cad9b982763f.tar.xz
* Refactor: Break out permissions code into a separate region PermissionsModule
Diffstat (limited to 'OpenSim/Region/Environment/Modules/World/Permissions')
-rw-r--r--OpenSim/Region/Environment/Modules/World/Permissions/PermissionsModule.cs698
1 files changed, 698 insertions, 0 deletions
diff --git a/OpenSim/Region/Environment/Modules/World/Permissions/PermissionsModule.cs b/OpenSim/Region/Environment/Modules/World/Permissions/PermissionsModule.cs
new file mode 100644
index 0000000..de02702
--- /dev/null
+++ b/OpenSim/Region/Environment/Modules/World/Permissions/PermissionsModule.cs
@@ -0,0 +1,698 @@
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 OpenSim 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
28using libsecondlife;
29using Nini.Config;
30
31using OpenSim.Region.Environment.Interfaces;
32using OpenSim.Region.Environment.Scenes;
33
34namespace OpenSim.Region.Environment.Modules.World.Permissions
35{
36 public class PermissionsModule : IRegionModule, IScenePermissions
37 {
38 protected Scene m_scene;
39
40 // These are here for testing. They will be taken out
41
42 //private uint PERM_ALL = (uint)2147483647;
43 private uint PERM_COPY = (uint)32768;
44 //private uint PERM_MODIFY = (uint)16384;
45 private uint PERM_MOVE = (uint)524288;
46 //private uint PERM_TRANS = (uint)8192;
47 private uint PERM_LOCKED = (uint)540672;
48
49 // Bypasses the permissions engine
50 private bool m_bypassPermissions = false;
51
52 public bool BypassPermissions
53 {
54 get { return m_bypassPermissions; }
55 set { m_bypassPermissions = value; }
56 }
57
58 #region IRegionModule Members
59
60 public void Initialise(Scene scene, IConfigSource config)
61 {
62 m_scene = scene;
63
64 // FIXME: Possibly move all permissions related stuff to its own section
65 IConfig myConfig = config.Configs["Startup"];
66
67 m_bypassPermissions = !myConfig.GetBoolean("serverside_object_permissions", false);
68
69 m_scene.RegisterModuleInterface<IScenePermissions>(this);
70 }
71
72 public void PostInitialise()
73 {
74 }
75
76 public void Close()
77 {
78 }
79
80 public string Name
81 {
82 get { return "PermissionsModule"; }
83 }
84
85 public bool IsSharedModule
86 {
87 get { return false; }
88 }
89
90 #endregion
91
92 protected virtual void SendPermissionError(LLUUID user, string reason)
93 {
94 m_scene.EventManager.TriggerPermissionError(user, reason);
95 }
96
97 protected virtual bool IsAdministrator(LLUUID user)
98 {
99 if (m_bypassPermissions)
100 {
101 return true;
102 }
103
104 // If there is no master avatar, return false
105 if (m_scene.RegionInfo.MasterAvatarAssignedUUID != LLUUID.Zero)
106 {
107 return m_scene.RegionInfo.MasterAvatarAssignedUUID == user;
108 }
109
110 return false;
111 }
112
113 public virtual bool IsEstateManager(LLUUID user)
114 {
115 if (m_bypassPermissions)
116 {
117 return true;
118 }
119
120 if (user != LLUUID.Zero)
121 {
122 LLUUID[] estatemanagers = m_scene.RegionInfo.EstateSettings.estateManagers;
123 for (int i = 0; i < estatemanagers.Length; i++)
124 {
125 if (estatemanagers[i] == user)
126 return true;
127 }
128 }
129
130 return false;
131 }
132
133 protected virtual bool IsGridUser(LLUUID user)
134 {
135 return true;
136 }
137
138 protected virtual bool IsGuest(LLUUID user)
139 {
140 return false;
141 }
142
143 public virtual bool CanRezObject(LLUUID user, LLVector3 position)
144 {
145 bool permission = false;
146
147 string reason = "Insufficient permission";
148
149 ILandObject land = m_scene.LandChannel.getLandObject(position.X, position.Y);
150 if (land == null) return false;
151
152 if ((land.landData.landFlags & ((int)Parcel.ParcelFlags.CreateObjects)) ==
153 (int)Parcel.ParcelFlags.CreateObjects)
154 permission = true;
155
156 //TODO: check for group rights
157
158 if (IsAdministrator(user))
159 {
160 permission = true;
161 }
162 else
163 {
164 reason = "Not an administrator";
165 }
166
167 if (GenericParcelPermission(user, position))
168 {
169 permission = true;
170 }
171 else
172 {
173 reason = "Not the parcel owner";
174 }
175
176 if (!permission)
177 SendPermissionError(user, reason);
178
179 return permission;
180 }
181
182 /// <see cref="Opensim.Region.Environment.Interfaces.IScenePermissions></see>
183 public virtual bool CanObjectEntry(LLUUID user, LLVector3 oldPos, LLVector3 newPos)
184 {
185 if ((newPos.X > 257f || newPos.X < -1f || newPos.Y > 257f || newPos.Y < -1f))
186 {
187 return true;
188 }
189
190 ILandObject land1 = m_scene.LandChannel.getLandObject(oldPos.X, oldPos.Y);
191 ILandObject land2 = m_scene.LandChannel.getLandObject(newPos.X, newPos.Y);
192
193 if (land1 == null || land2 == null)
194 {
195 return false;
196 }
197 if (land2 == null)
198 {
199 // need this for crossing borders
200 return true;
201 }
202
203 if (land1.landData.globalID == land2.landData.globalID)
204 {
205 return true;
206 }
207
208 if ((land2.landData.landFlags & ((int)Parcel.ParcelFlags.AllowAllObjectEntry)) != 0)
209 {
210 return true;
211 }
212
213 //TODO: check for group rights
214
215 if (GenericParcelPermission(user, newPos))
216 {
217 return true;
218 }
219
220 SendPermissionError(user, "Not allowed to move objects in this parcel!");
221
222 return false;
223 }
224
225 #region Object Permissions
226
227 public virtual uint GenerateClientFlags(LLUUID user, LLUUID objID)
228 {
229 // Here's the way this works,
230 // ObjectFlags and Permission flags are two different enumerations
231 // ObjectFlags, however, tells the client to change what it will allow the user to do.
232 // So, that means that all of the permissions type ObjectFlags are /temporary/ and only
233 // supposed to be set when customizing the objectflags for the client.
234
235 // These temporary objectflags get computed and added in this function based on the
236 // Permission mask that's appropriate!
237 // Outside of this method, they should never be added to objectflags!
238 // -teravus
239
240 SceneObjectPart task=m_scene.GetSceneObjectPart(objID);
241
242 // this shouldn't ever happen.. return no permissions/objectflags.
243 if (task == null)
244 return (uint)0;
245
246 uint objflags = task.GetEffectiveObjectFlags();
247 LLUUID objectOwner = task.OwnerID;
248
249
250 // Remove any of the objectFlags that are temporary. These will get added back if appropriate
251 // in the next bit of code
252
253 objflags &= (uint)
254 ~(LLObject.ObjectFlags.ObjectCopy | // Tells client you can copy the object
255 LLObject.ObjectFlags.ObjectModify | // tells client you can modify the object
256 LLObject.ObjectFlags.ObjectMove | // tells client that you can move the object (only, no mod)
257 LLObject.ObjectFlags.ObjectTransfer | // tells the client that you can /take/ the object if you don't own it
258 LLObject.ObjectFlags.ObjectYouOwner | // Tells client that you're the owner of the object
259 LLObject.ObjectFlags.ObjectYouOfficer // Tells client that you've got group object editing permission. Used when ObjectGroupOwned is set
260 );
261
262 // Creating the three ObjectFlags options for this method to choose from.
263 // Customize the OwnerMask
264 uint objectOwnerMask = ApplyObjectModifyMasks(task.OwnerMask, objflags);
265 objectOwnerMask |= (uint)LLObject.ObjectFlags.ObjectYouOwner;
266
267 // Customize the GroupMask
268 uint objectGroupMask = ApplyObjectModifyMasks(task.GroupMask, objflags);
269
270 // Customize the EveryoneMask
271 uint objectEveryoneMask = ApplyObjectModifyMasks(task.EveryoneMask, objflags);
272
273
274 // Hack to allow collaboration until Groups and Group Permissions are implemented
275 if ((objectEveryoneMask & (uint)LLObject.ObjectFlags.ObjectMove) != 0)
276 objectEveryoneMask |= (uint)LLObject.ObjectFlags.ObjectModify;
277
278 if (m_bypassPermissions)
279 return objectOwnerMask;
280
281 // Object owners should be able to edit their own content
282 if (user == objectOwner)
283 {
284 return objectOwnerMask;
285 }
286
287 // Users should be able to edit what is over their land.
288 ILandObject parcel = m_scene.LandChannel.getLandObject(task.AbsolutePosition.X, task.AbsolutePosition.Y);
289 if (parcel != null && parcel.landData.ownerID == user)
290 return objectOwnerMask;
291
292 // Admin objects should not be editable by the above
293 if (IsAdministrator(objectOwner))
294 return objectEveryoneMask;
295
296 // Estate users should be able to edit anything in the sim
297 if (IsEstateManager(user))
298 return objectOwnerMask;
299
300
301
302 // Admin should be able to edit anything in the sim (including admin objects)
303 if (IsAdministrator(user))
304 return objectOwnerMask;
305
306
307 return objectEveryoneMask;
308 }
309
310 private uint ApplyObjectModifyMasks(uint setPermissionMask, uint objectFlagsMask)
311 {
312 // We are adding the temporary objectflags to the object's objectflags based on the
313 // permission flag given. These change the F flags on the client.
314
315 if ((setPermissionMask & (uint)PermissionMask.Copy) != 0)
316 {
317 objectFlagsMask |= (uint)LLObject.ObjectFlags.ObjectCopy;
318 }
319
320 if ((setPermissionMask & (uint)PermissionMask.Move) != 0)
321 {
322 objectFlagsMask |= (uint)LLObject.ObjectFlags.ObjectMove;
323 }
324
325 if ((setPermissionMask & (uint)PermissionMask.Modify) != 0)
326 {
327 objectFlagsMask |= (uint)LLObject.ObjectFlags.ObjectModify;
328 }
329
330 if ((setPermissionMask & (uint)PermissionMask.Transfer) != 0)
331 {
332 objectFlagsMask |= (uint)LLObject.ObjectFlags.ObjectTransfer;
333 }
334
335 return objectFlagsMask;
336 }
337
338 protected virtual bool GenericObjectPermission(LLUUID currentUser, LLUUID objId)
339 {
340 // Default: deny
341 bool permission = false;
342 bool locked = false;
343
344 if (!m_scene.Entities.ContainsKey(objId))
345 {
346 return false;
347 }
348
349 // If it's not an object, we cant edit it.
350 if ((!(m_scene.Entities[objId] is SceneObjectGroup)))
351 {
352 return false;
353 }
354
355
356 SceneObjectGroup group = (SceneObjectGroup)m_scene.Entities[objId];
357
358 LLUUID objectOwner = group.OwnerID;
359 locked = ((group.RootPart.OwnerMask & PERM_LOCKED) == 0);
360
361 // People shouldn't be able to do anything with locked objects, except the Administrator
362 // The 'set permissions' runs through a different permission check, so when an object owner
363 // sets an object locked, the only thing that they can do is unlock it.
364 //
365 // Nobody but the object owner can set permissions on an object
366 //
367
368 if (locked && (!IsAdministrator(currentUser)))
369 {
370 return false;
371 }
372
373 // Object owners should be able to edit their own content
374 if (currentUser == objectOwner)
375 {
376 permission = true;
377 }
378
379 // Users should be able to edit what is over their land.
380 ILandObject parcel = m_scene.LandChannel.getLandObject(group.AbsolutePosition.X, group.AbsolutePosition.Y);
381 if ((parcel != null) && (parcel.landData.ownerID == currentUser))
382 {
383 permission = true;
384 }
385
386 // Estate users should be able to edit anything in the sim
387 if (IsEstateManager(currentUser))
388 {
389 permission = true;
390 }
391
392 // Admin objects should not be editable by the above
393 if (IsAdministrator(objectOwner))
394 {
395 permission = false;
396 }
397
398 // Admin should be able to edit anything in the sim (including admin objects)
399 if (IsAdministrator(currentUser))
400 {
401 permission = true;
402 }
403
404 return permission;
405 }
406
407 /// <see cref="Opensim.Region.Environment.Interfaces.IScenePermissions></see>
408 public virtual bool CanDeRezObject(LLUUID user, LLUUID obj)
409 {
410 return GenericObjectPermission(user, obj);
411 }
412
413 public virtual bool CanEditObject(LLUUID user, LLUUID obj)
414 {
415 return GenericObjectPermission(user, obj);
416 }
417
418 public virtual bool CanEditObjectPosition(LLUUID user, LLUUID obj)
419 {
420 bool permission = GenericObjectPermission(user, obj);
421 if (!permission)
422 {
423 if (!m_scene.Entities.ContainsKey(obj))
424 {
425 return false;
426 }
427
428 // The client
429 // may request to edit linked parts, and therefore, it needs
430 // to also check for SceneObjectPart
431
432 // If it's not an object, we cant edit it.
433 if ((!(m_scene.Entities[obj] is SceneObjectGroup)))
434 {
435 return false;
436 }
437
438
439 SceneObjectGroup task = (SceneObjectGroup)m_scene.Entities[obj];
440
441
442 LLUUID taskOwner = null;
443 // Added this because at this point in time it wouldn't be wise for
444 // the administrator object permissions to take effect.
445 LLUUID objectOwner = task.OwnerID;
446
447 // Anyone can move
448 if ((task.RootPart.EveryoneMask & PERM_MOVE) != 0)
449 permission = true;
450
451 // Locked
452 if ((task.RootPart.OwnerMask & PERM_LOCKED) == 0)
453 permission = false;
454
455 }
456 else
457 {
458 bool locked = false;
459 if (!m_scene.Entities.ContainsKey(obj))
460 {
461 return false;
462 }
463
464 // If it's not an object, we cant edit it.
465 if ((!(m_scene.Entities[obj] is SceneObjectGroup)))
466 {
467 return false;
468 }
469
470
471 SceneObjectGroup group = (SceneObjectGroup)m_scene.Entities[obj];
472
473 LLUUID objectOwner = group.OwnerID;
474 locked = ((group.RootPart.OwnerMask & PERM_LOCKED) == 0);
475
476
477 // This is an exception to the generic object permission.
478 // Administrators who lock their objects should not be able to move them,
479 // however generic object permission should return true.
480 // This keeps locked objects from being affected by random click + drag actions by accident
481 // and allows the administrator to grab or delete a locked object.
482
483 // Administrators and estate managers are still able to click+grab locked objects not
484 // owned by them in the scene
485 // This is by design.
486
487 if (locked && (user == objectOwner))
488 return false;
489 }
490 return permission;
491 }
492
493 public virtual bool CanCopyObject(LLUUID user, LLUUID obj)
494 {
495 bool permission = GenericObjectPermission(user, obj);
496 if (!permission)
497 {
498 if (!m_scene.Entities.ContainsKey(obj))
499 {
500 return false;
501 }
502
503 // If it's not an object, we cant edit it.
504 if (!(m_scene.Entities[obj] is SceneObjectGroup))
505 {
506 return false;
507 }
508
509 SceneObjectGroup task = (SceneObjectGroup)m_scene.Entities[obj];
510 LLUUID taskOwner = null;
511 // Added this because at this point in time it wouldn't be wise for
512 // the administrator object permissions to take effect.
513 LLUUID objectOwner = task.OwnerID;
514 if ((task.RootPart.EveryoneMask & PERM_COPY) != 0)
515 permission = true;
516 }
517 return permission;
518 }
519
520 public virtual bool CanReturnObject(LLUUID user, LLUUID obj)
521 {
522 return GenericObjectPermission(user, obj);
523 }
524
525 #endregion
526
527 #region Communication Permissions
528
529 protected virtual bool GenericCommunicationPermission(LLUUID user, LLUUID target)
530 {
531 bool permission = false;
532 string reason = "Only registered users may communicate with another account.";
533
534 if (IsGridUser(user))
535 permission = true;
536
537 if (!IsGridUser(user))
538 {
539 permission = false;
540 reason = "The person that you are messaging is not a registered user.";
541 }
542 if (IsAdministrator(user))
543 permission = true;
544
545 if (IsEstateManager(user))
546 permission = true;
547
548 if (!permission)
549 SendPermissionError(user, reason);
550
551 return permission;
552 }
553
554 public virtual bool CanInstantMessage(LLUUID user, LLUUID target)
555 {
556 return GenericCommunicationPermission(user, target);
557 }
558
559 public virtual bool CanInventoryTransfer(LLUUID user, LLUUID target)
560 {
561 return GenericCommunicationPermission(user, target);
562 }
563
564 #endregion
565
566 public virtual bool CanEditScript(LLUUID user, LLUUID script)
567 {
568 return IsAdministrator(user);
569 }
570
571 public virtual bool CanRunScript(LLUUID user, LLUUID script)
572 {
573 return IsAdministrator(user);
574 }
575
576 public virtual bool CanRunConsoleCommand(LLUUID user)
577 {
578 return IsAdministrator(user);
579 }
580
581 public virtual bool CanTerraform(LLUUID user, LLVector3 position)
582 {
583 bool permission = false;
584
585 // Estate override
586 if (GenericEstatePermission(user))
587 permission = true;
588
589 float X = position.X;
590 float Y = position.Y;
591
592 if (X > 255)
593 X = 255;
594 if (Y > 255)
595 Y = 255;
596 if (X < 0)
597 X = 0;
598 if (Y < 0)
599 Y = 0;
600
601 // Land owner can terraform too
602 ILandObject parcel = m_scene.LandChannel.getLandObject(X, Y);
603 if (parcel != null && GenericParcelPermission(user, parcel))
604 permission = true;
605
606 if (!permission)
607 SendPermissionError(user, "Not authorized to terraform at this location.");
608
609 return permission;
610 }
611
612 #region Estate Permissions
613
614 public virtual bool GenericEstatePermission(LLUUID user)
615 {
616 // Default: deny
617 bool permission = false;
618
619 // Estate admins should be able to use estate tools
620 if (IsEstateManager(user))
621 permission = true;
622
623 // Administrators always have permission
624 if (IsAdministrator(user))
625 permission = true;
626
627 return permission;
628 }
629
630 public virtual bool CanEditEstateTerrain(LLUUID user)
631 {
632 return GenericEstatePermission(user);
633 }
634
635 public virtual bool CanRestartSim(LLUUID user)
636 {
637 // Since this is potentially going on a grid...
638
639 return GenericEstatePermission(user);
640 //return m_scene.RegionInfo.MasterAvatarAssignedUUID == user;
641 }
642
643 #endregion
644
645 #region Parcel Permissions
646
647 protected virtual bool GenericParcelPermission(LLUUID user, ILandObject parcel)
648 {
649 bool permission = false;
650
651 if (parcel.landData.ownerID == user)
652 {
653 permission = true;
654 }
655
656 if (parcel.landData.isGroupOwned)
657 {
658 // TODO: Need to do some extra checks here. Requires group code.
659 }
660
661 if (IsEstateManager(user))
662 {
663 permission = true;
664 }
665
666 if (IsAdministrator(user))
667 {
668 permission = true;
669 }
670
671 return permission;
672 }
673
674 protected virtual bool GenericParcelPermission(LLUUID user, LLVector3 pos)
675 {
676 ILandObject parcel = m_scene.LandChannel.getLandObject(pos.X, pos.Y);
677 if (parcel == null) return false;
678 return GenericParcelPermission(user, parcel);
679 }
680
681 public virtual bool CanEditParcel(LLUUID user, ILandObject parcel)
682 {
683 return GenericParcelPermission(user, parcel);
684 }
685
686 public virtual bool CanSellParcel(LLUUID user, ILandObject parcel)
687 {
688 return GenericParcelPermission(user, parcel);
689 }
690
691 public virtual bool CanAbandonParcel(LLUUID user, ILandObject parcel)
692 {
693 return GenericParcelPermission(user, parcel);
694 }
695
696 #endregion
697 }
698}