PageRenderTime 32ms CodeModel.GetById 13ms app.highlight 14ms RepoModel.GetById 1ms app.codeStats 0ms

/indra/llinventory/llpermissions.h

https://bitbucket.org/lindenlab/viewer-beta/
C++ Header | 458 lines | 162 code | 76 blank | 220 comment | 3 complexity | 9e8dd839bd5092d5999159dc5bfc2980 MD5 | raw file
  1/** 
  2 * @file llpermissions.h
  3 * @brief Permissions structures for objects.
  4 *
  5 * $LicenseInfo:firstyear=2002&license=viewerlgpl$
  6 * Second Life Viewer Source Code
  7 * Copyright (C) 2010, Linden Research, Inc.
  8 * 
  9 * This library is free software; you can redistribute it and/or
 10 * modify it under the terms of the GNU Lesser General Public
 11 * License as published by the Free Software Foundation;
 12 * version 2.1 of the License only.
 13 * 
 14 * This library is distributed in the hope that it will be useful,
 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 17 * Lesser General Public License for more details.
 18 * 
 19 * You should have received a copy of the GNU Lesser General Public
 20 * License along with this library; if not, write to the Free Software
 21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 22 * 
 23 * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
 24 * $/LicenseInfo$
 25 */
 26
 27#ifndef LL_LLPERMISSIONS_H
 28#define LL_LLPERMISSIONS_H
 29
 30#include "llpermissionsflags.h"
 31#include "llsd.h"
 32#include "lluuid.h"
 33#include "llxmlnode.h"
 34#include "reflective.h"
 35#include "llinventorytype.h"
 36
 37// prototypes
 38class LLMessageSystem;
 39extern void mask_to_string(U32 mask, char* str);
 40extern std::string mask_to_string(U32 mask);
 41template<class T> class LLMetaClassT;
 42
 43//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 44// Class LLPermissions
 45//
 46// Class which encapsulates object and inventory permissions/ownership/etc.
 47//
 48// Permissions where originally a static state creator/owner and set
 49// of cap bits. Since then, it has grown to include group information,
 50// last owner, masks for different people. The implementation has been
 51// chosen such that a uuid is stored for each current/past owner, and
 52// a bitmask is stored for the base permissions, owner permissions,
 53// group permissions, and everyone else permissions.
 54//
 55// The base permissions represent the most permissive state that the
 56// permissions can possibly be in. Thus, if the base permissions do
 57// not allow copying, no one can ever copy the object. The permissions
 58// also maintain a tree-like hierarchy of permissions, thus, if we
 59// (for sake of discussions) denote more permissive as '>', then this
 60// is invariant:
 61//
 62// base mask >= owner mask >= group mask
 63//                         >= everyone mask
 64//                         >= next owner mask
 65// NOTE: the group mask does not effect everyone or next, everyone
 66// does not effect group or next, etc.
 67//
 68// It is considered a fair use right to move or delete any object you
 69// own.  Another fair use right is the ability to give away anything
 70// which you cannot copy. One way to look at that is that if you have
 71// a unique item, you can always give that one copy you have to
 72// someone else.
 73//
 74// Most of the bitmask is easy to understand, PERM_COPY means you can
 75// copy !PERM_TRANSFER means you cannot transfer, etc. Given that we
 76// now track the concept of 'next owner' inside of the permissions
 77// object, we can describe some new meta-meaning to the PERM_MODIFY
 78// flag. PERM_MODIFY is usually meant to note if you can change an
 79// item, but since we record next owner permissions, we can interpret
 80// a no-modify object as 'you cannot modify this object and you cannot
 81// make derivative works.' When evaluating functionality, and
 82// comparisons against permissions, keep this concept in mind for
 83// logical consistency.
 84//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 85
 86class LLPermissions : public LLReflective
 87{
 88private:
 89	LLUUID			mCreator;				// null if object created by system
 90	LLUUID			mOwner;					// null if object "unowned" (owned by system)
 91	LLUUID			mLastOwner;				// object's last owner
 92	LLUUID			mGroup;					// The group association
 93
 94	PermissionMask	mMaskBase;				// initially permissive, progressively AND restricted by each owner
 95
 96	PermissionMask	mMaskOwner;				// set by owner, applies to owner only, restricts lower permissions
 97	PermissionMask	mMaskEveryone;			// set by owner, applies to everyone else
 98
 99	PermissionMask	mMaskGroup;				// set by owner, applies to group that is associated with permissions
100
101	PermissionMask mMaskNextOwner;			// set by owner, applied to base on transfer.
102
103	// Usually set in the fixOwnership() method based on current uuid
104	// values.
105	bool mIsGroupOwned;
106
107	// Correct for fair use - you can never take away the right to
108	// move stuff you own, and you can never take away the right to
109	// transfer something you cannot otherwise copy.
110	void fixFairUse();
111
112	// Fix internal consistency for group/agent ownership
113	void fixOwnership();
114
115public:
116	static const LLPermissions DEFAULT;
117
118	LLPermissions();						// defaults to created by system
119	//~LLPermissions();
120
121	// base initialization code
122	void init(const LLUUID& creator, const LLUUID& owner,
123			  const LLUUID& last_owner, const LLUUID& group);
124	void initMasks(PermissionMask base, PermissionMask owner,
125				   PermissionMask everyone, PermissionMask group,
126				   PermissionMask next);
127	// adjust permissions based on inventory type.
128	void initMasks(LLInventoryType::EType type);
129
130	//
131	// ACCESSORS
132	//
133
134	// return the agent_id of the agent that created the item
135	const LLUUID&	getCreator() 		const	{ return mCreator; }
136
137	// return the agent_id of the owner. returns LLUUID::null if group
138	// owned or public (a really big group).
139	const LLUUID&	getOwner() 			const	{ return mOwner; }
140
141	// return the group_id of the group associated with the
142	// object.
143	const LLUUID&	getGroup() 			const	{ return mGroup; }
144
145	// return the agent_id of the last agent owner. Only returns
146	// LLUUID::null if there has never been a previous owner (*note: this is apparently not true, say for textures in inventory, it may return LLUUID::null even if there was a previous owner).
147	const LLUUID&	getLastOwner() 		const	{ return mLastOwner; }
148
149	U32				getMaskBase() 		const	{ return mMaskBase; }
150	U32				getMaskOwner() 		const	{ return mMaskOwner; }
151	U32				getMaskGroup() 		const	{ return mMaskGroup; }
152	U32				getMaskEveryone() 	const	{ return mMaskEveryone; }
153	U32 getMaskNextOwner() const { return mMaskNextOwner; }
154
155	// return TRUE if the object has any owner
156	bool isOwned() const { return (mOwner.notNull() || mIsGroupOwned); }
157
158	// return TRUE if group_id is owner.
159	bool isGroupOwned() const { return mIsGroupOwned; }
160
161	// This API returns TRUE if the object is owned at all, and FALSE
162	// otherwise. If it is owned at all, owner id is filled with
163	// either the owner id or the group id, and the is_group_owned
164	// parameter is appropriately filled. The values of owner_id and
165	// is_group_owned are not changed if the object is not owned.
166	BOOL getOwnership(LLUUID& owner_id, BOOL& is_group_owned) const;
167
168	// Gets the 'safe' owner.  This should never return LLUUID::null.
169	// If no group owned, return the agent owner id normally.
170	// If group owned, return the group id.
171	// If not owned, return a random uuid which should have no power.
172	LLUUID getSafeOwner() const;
173
174	// return a cheap crc
175	U32 getCRC32() const;
176
177
178	//
179	// MANIPULATORS
180	//
181
182	// Fix hierarchy of permissions, applies appropriate permissions
183	// at each level to ensure that base permissions are respected,
184	// and also ensures that if base cannot transfer, then group and
185	// other cannot copy.
186	void fix();
187
188	// All of these methods just do exactly what they say. There is no
189	// permissions checking to see if the operation is allowed, and do
190	// not fix the permissions hierarchy. So please only use these
191	// methods when you are know what you're doing and coding on
192	// behalf of the system - ie, acting as god.
193	void set(const LLPermissions& permissions);
194	void setMaskBase(U32 mask)	   { mMaskBase = mask; }
195	void setMaskOwner(U32 mask)	   { mMaskOwner = mask; }
196	void setMaskEveryone(U32 mask) { mMaskEveryone = mask;}
197	void setMaskGroup(U32 mask)	   { mMaskGroup = mask;}
198	void setMaskNext(U32 mask) { mMaskNextOwner = mask; }
199
200	// Allow accumulation of permissions. Results in the tightest
201	// permissions possible. In the case of clashing UUIDs, it sets
202	// the ID to LLUUID::null.
203	void accumulate(const LLPermissions& perm);
204
205	//
206	// CHECKED MANIPULATORS 
207	//
208
209	// These functions return true on success.  They return false if
210	// the given agent isn't allowed to make the change.  You can pass
211	// LLUUID::null as the agent id if the change is being made by the
212	// simulator itself, not on behalf of any agent - this will always
213	// succeed. Passing in group id of LLUUID:null means no group, and
214	// does not offer special permission to do anything.
215
216	// saves last owner, sets current owner, and sets the group.
217	// set is_atomic = true means that this permission represents
218	// an atomic permission and not a collection of permissions.
219	// Currently, the only way to have a collection is when an object
220	// has inventory and is then itself rolled up into an inventory
221	// item.
222	BOOL setOwnerAndGroup(const LLUUID& agent, const LLUUID& owner, const LLUUID& group, bool is_atomic);	
223
224	// only call this if you know what you're doing
225	// there are usually perm-bit consequences when the 
226	// ownerhsip changes
227	void yesReallySetOwner(const LLUUID& owner, bool group_owned);
228
229	// Last owner doesn't have much in the way of permissions so it's 
230	//not too dangerous to do this. 
231	void setLastOwner(const LLUUID& last_owner);
232
233	// saves last owner, sets owner to uuid null, sets group
234	// owned. group_id must be the group of the object (that's who it
235	// is being deeded to) and the object must be group
236	// modify. Technically, the agent id and group id are not
237	// necessary, but I wanted this function to look like the other
238	// checked manipulators (since that is how it is used.) If the
239	// agent is the system or (group == mGroup and group modify and
240	// owner transfer) then this function will deed the permissions,
241	// set the next owner mask, and return TRUE. Otherwise, no change
242	// is effected, and the function returns FALSE.
243	BOOL deedToGroup(const LLUUID& agent, const LLUUID& group);
244	// Attempt to set or clear the given bitmask.  Returns TRUE if you
245	// are allowed to modify the permissions.  If you attempt to turn
246	// on bits not allowed by the base bits, the function will return
247	// TRUE, but those bits will not be set.
248	BOOL setBaseBits( const LLUUID& agent, BOOL set, PermissionMask bits);
249	BOOL setOwnerBits( const LLUUID& agent, BOOL set, PermissionMask bits);
250	BOOL setGroupBits( const LLUUID& agent, const LLUUID& group, BOOL set, PermissionMask bits);
251	BOOL setEveryoneBits(const LLUUID& agent, const LLUUID& group, BOOL set, PermissionMask bits);
252	BOOL setNextOwnerBits(const LLUUID& agent, const LLUUID& group, BOOL set, PermissionMask bits);
253	
254	// This is currently only used in the Viewer to handle calling cards
255	// where the creator is actually used to store the target. Use with care.
256	void setCreator(const LLUUID& creator) { mCreator = creator; }
257	
258	//
259	// METHODS
260	//
261
262	// All the allow* functions return true if the given agent or
263	// group can perform the function. Prefer using this set of
264	// operations to check permissions on an object.  These return
265	// true if the given agent or group can perform the function.
266	// They also return true if the object isn't owned, or the
267	// requesting agent is a system agent.  See llpermissionsflags.h
268	// for bits.
269	bool allowOperationBy(PermissionBit op, const LLUUID& agent, const LLUUID& group = LLUUID::null) const;
270
271	inline bool allowModifyBy(const LLUUID &agent_id) const;
272	inline bool allowCopyBy(const LLUUID& agent_id) const;
273	inline bool allowMoveBy(const LLUUID& agent_id) const;
274	inline bool allowModifyBy(const LLUUID &agent_id, const LLUUID& group) const;
275	inline bool allowCopyBy(const LLUUID& agent_id, const LLUUID& group) const;
276	inline bool allowMoveBy(const LLUUID &agent_id, const LLUUID &group) const;
277
278	// This somewhat specialized function is meant for testing if the
279	// current owner is allowed to transfer to the specified agent id.
280	inline bool allowTransferTo(const LLUUID &agent_id) const;
281
282	//
283	// DEPRECATED.
284	//
285	// These return true if the given agent can perform the function.
286	// They also return true if the object isn't owned, or the
287	// requesting agent is a system agent.  See llpermissionsflags.h
288	// for bits.
289	//BOOL	allowDeleteBy(const LLUUID& agent_id) 	const		{ return allowModifyBy(agent_id); }
290	//BOOL	allowEditBy(const LLUUID& agent_id) 	const		{ return allowModifyBy(agent_id); }
291	// saves last owner and sets current owner
292	//BOOL setOwner(const LLUUID& agent, const LLUUID& owner);	
293	// This method saves the last owner, sets the current owner to the
294	// one provided, and sets the base mask as indicated.
295	//BOOL setOwner(const LLUUID& agent, const LLUUID& owner, U32 new_base_mask);
296
297	// Attempt to set or clear the given bitmask.  Returns TRUE if you
298	// are allowed to modify the permissions.  If you attempt to turn
299	// on bits not allowed by the base bits, the function will return
300	// TRUE, but those bits will not be set.
301	//BOOL setGroupBits( const LLUUID& agent, BOOL set, PermissionMask bits);
302	//BOOL setEveryoneBits(const LLUUID& agent, BOOL set, PermissionMask bits);
303
304	//
305	// MISC METHODS and OPERATORS
306	//
307
308	LLSD	packMessage() const;
309	void	unpackMessage(LLSD perms);
310
311	// For messaging system support
312	void	packMessage(LLMessageSystem* msg) const;
313	void	unpackMessage(LLMessageSystem* msg, const char* block, S32 block_num = 0);
314
315	// Load/save support
316	BOOL	importFile(LLFILE* fp);
317	BOOL	exportFile(LLFILE* fp) const;
318
319	BOOL	importLegacyStream(std::istream& input_stream);
320	BOOL	exportLegacyStream(std::ostream& output_stream) const;
321
322	bool operator==(const LLPermissions &rhs) const;
323	bool operator!=(const LLPermissions &rhs) const;
324
325	friend std::ostream& operator<<(std::ostream &s, const LLPermissions &perm);
326
327	// Reflection.
328	friend class LLMetaClassT<LLPermissions>;
329	virtual const LLMetaClass& getMetaClass() const;
330};
331
332// Inlines
333bool LLPermissions::allowModifyBy(const LLUUID& agent, const LLUUID& group) const
334{
335	return allowOperationBy(PERM_MODIFY, agent, group);
336}
337
338bool LLPermissions::allowCopyBy(const LLUUID& agent, const LLUUID& group) const
339{
340	return allowOperationBy(PERM_COPY, agent, group);
341}
342
343
344bool LLPermissions::allowMoveBy(const LLUUID& agent, const LLUUID& group) const
345{
346	return allowOperationBy(PERM_MOVE, agent, group);
347}
348
349bool LLPermissions::allowModifyBy(const LLUUID& agent) const
350{
351	return allowOperationBy(PERM_MODIFY, agent, LLUUID::null);
352}
353
354bool LLPermissions::allowCopyBy(const LLUUID& agent) const
355{
356	return allowOperationBy(PERM_COPY, agent, LLUUID::null);
357}
358
359bool LLPermissions::allowMoveBy(const LLUUID& agent) const
360{
361	return allowOperationBy(PERM_MOVE, agent, LLUUID::null);
362}
363
364bool LLPermissions::allowTransferTo(const LLUUID &agent_id) const
365{
366	if (mIsGroupOwned)
367	{
368		return allowOperationBy(PERM_TRANSFER, mGroup, mGroup);
369	}
370	else
371	{
372		return ((mOwner == agent_id) ? TRUE : allowOperationBy(PERM_TRANSFER, mOwner));
373	}
374}
375
376//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
377// Class LLAggregatePermissions
378//
379// Class which encapsulates object and inventory permissions,
380// ownership, etc. Currently, it only aggregates PERM_COPY,
381// PERM_MODIFY, and PERM_TRANSFER.
382//
383// Usually you will construct an instance and hand the object several
384// permissions masks to aggregate the copy, modify, and
385// transferability into a nice trinary value.
386//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
387
388class LLAggregatePermissions
389{
390public:
391	enum EValue
392	{
393		AP_EMPTY = 0x00,
394		AP_NONE = 0x01,
395		AP_SOME = 0x02,
396		AP_ALL = 0x03
397	};
398
399	// construct an empty aggregate permissions
400	LLAggregatePermissions();
401
402	// pass in a PERM_COPY, PERM_TRANSFER, etc, and get out a EValue
403	// enumeration describing the current aggregate permissions.
404	EValue getValue(PermissionBit bit) const;
405
406	// returns the permissions packed into the 6 LSB of a U8:
407	// 00TTMMCC
408	// where TT = transfer, MM = modify, and CC = copy
409	// LSB is to the right
410	U8 getU8() const;
411
412	// return TRUE is the aggregate permissions are empty, otherwise FALSE.
413	BOOL isEmpty() const ;
414
415	// pass in a PERM_COPY, PERM_TRANSFER, etc, and an EValue
416	// enumeration to specifically set that value. Not implemented
417	// because I'm not sure it's a useful api.
418	//void setValue(PermissionBit bit, EValue);
419
420	// Given a mask, aggregate the useful permissions.
421	void aggregate(PermissionMask mask);
422
423	// Aggregate aggregates
424	void aggregate(const LLAggregatePermissions& ag);
425
426	// message handling
427	void packMessage(LLMessageSystem* msg, const char* field) const;
428	void unpackMessage(LLMessageSystem* msg, const char* block, const char *field, S32 block_num = 0);
429
430	static const LLAggregatePermissions empty;
431	
432	friend std::ostream& operator<<(std::ostream &s, const LLAggregatePermissions &perm);
433
434protected:
435	enum EPermIndex
436	{
437		PI_COPY = 0,
438		PI_MODIFY = 1,
439		PI_TRANSFER = 2,
440		PI_END = 3,
441		PI_COUNT = 3
442	};
443	void aggregateBit(EPermIndex idx, BOOL allowed);
444	void aggregateIndex(EPermIndex idx, U8 bits);
445	static EPermIndex perm2PermIndex(PermissionBit bit);
446
447	// structure used to store the aggregate so far.
448	U8 mBits[PI_COUNT];
449};
450
451// These functions convert between structured data and permissions as
452// appropriate for serialization. The permissions are a map of things
453// like 'creator_id', 'owner_id', etc, with the value copied from the
454// permission object.
455LLSD ll_create_sd_from_permissions(const LLPermissions& perm);
456LLPermissions ll_permissions_from_sd(const LLSD& sd_perm);
457
458#endif