llpermissions.cpp

Go to the documentation of this file.
00001 
00033 #include "linden_common.h"
00034 
00035 #include "llpermissions.h"
00036 
00037 // library includes
00038 #include "message.h"
00039 #include "metapropertyt.h"
00040 #include "llsd.h"
00041 
00045 
00046 const LLPermissions LLPermissions::DEFAULT;
00047 
00048 // No creator = created by system
00049 LLPermissions::LLPermissions()
00050 {
00051         init(LLUUID::null, LLUUID::null, LLUUID::null, LLUUID::null);
00052 }
00053 
00054 
00055 // Default to created by system
00056 void LLPermissions::init(const LLUUID& creator, const LLUUID& owner, const LLUUID& last_owner, const LLUUID& group)
00057 {
00058         mCreator        = creator;
00059         mOwner          = owner;
00060         mLastOwner      = last_owner;
00061         mGroup          = group;
00062 
00063         mMaskBase               = PERM_ALL;
00064         mMaskOwner              = PERM_ALL;
00065         mMaskEveryone   = PERM_ALL;
00066         mMaskGroup              = PERM_ALL;
00067         mMaskNextOwner = PERM_ALL;
00068         fixOwnership();
00069 }
00070 
00071 
00072 void LLPermissions::initMasks(PermissionMask base, PermissionMask owner,
00073                                                           PermissionMask everyone, PermissionMask group,
00074                                                           PermissionMask next)
00075 {
00076         mMaskBase               = base;
00077         mMaskOwner              = owner;
00078         mMaskEveryone   = everyone;
00079         mMaskGroup              = group;
00080         mMaskNextOwner = next;
00081         fixFairUse();
00082         fix();
00083 }
00084 
00085 BOOL LLPermissions::getOwnership(LLUUID& owner_id, BOOL& is_group_owned) const
00086 {
00087         if(mOwner.notNull())
00088         {
00089                 owner_id = mOwner;
00090                 is_group_owned = FALSE;
00091                 return TRUE;
00092         }
00093         else if(mIsGroupOwned)
00094         {
00095                 owner_id = mGroup;
00096                 is_group_owned = TRUE;
00097                 return TRUE;
00098         }
00099         return FALSE;
00100 }
00101 
00102 LLUUID LLPermissions::getSafeOwner() const
00103 {
00104         if(mOwner.notNull())
00105         {
00106                 return mOwner;
00107         }
00108         else if(mIsGroupOwned)
00109         {
00110                 return mGroup;
00111         }
00112         else
00113         {
00114                 llwarns << "LLPermissions::getSafeOwner() called with no valid owner!" << llendl;
00115                 LLUUID unused_uuid;
00116                 unused_uuid.generate();
00117 
00118                 return unused_uuid;
00119         }
00120 }
00121 
00122 U32 LLPermissions::getCRC32() const
00123 {
00124         U32 rv = mCreator.getCRC32();
00125         rv += mOwner.getCRC32();
00126         rv += mLastOwner.getCRC32();
00127         rv += mGroup.getCRC32();
00128         rv += mMaskBase + mMaskOwner + mMaskEveryone + mMaskGroup;
00129         return rv;
00130 }
00131 
00132 void LLPermissions::set(const LLPermissions& from)
00133 {
00134         mCreator        = from.mCreator;
00135         mOwner          = from.mOwner;
00136         mLastOwner      = from.mLastOwner;
00137         mGroup          = from.mGroup;
00138 
00139         mMaskBase               = from.mMaskBase;
00140         mMaskOwner              = from.mMaskOwner;
00141         mMaskEveryone   = from.mMaskEveryone;
00142         mMaskGroup              = from.mMaskGroup;
00143         mMaskNextOwner = from.mMaskNextOwner;
00144         mIsGroupOwned = from.mIsGroupOwned;
00145 }
00146 
00147 // Fix hierarchy of permissions. 
00148 void LLPermissions::fix()
00149 {
00150         mMaskOwner &= mMaskBase;
00151         mMaskGroup &= mMaskOwner;
00152         // next owner uses base, since you may want to sell locked objects.
00153         mMaskNextOwner &= mMaskBase;
00154         mMaskEveryone &= mMaskOwner;
00155         mMaskEveryone &= ~PERM_MODIFY;
00156         if(!(mMaskBase & PERM_TRANSFER) && !mIsGroupOwned)
00157         {
00158                 mMaskGroup &= ~PERM_COPY;
00159                 mMaskEveryone &= ~PERM_COPY;
00160                 // Do not set mask next owner to too restrictive because if we
00161                 // rez an object, it may require an ownership transfer during
00162                 // rez, which will note the overly restrictive perms, and then
00163                 // fix them to allow fair use, which may be different than the
00164                 // original intention.
00165         }
00166 }
00167 
00168 // Correct for fair use - you can never take away the right to move
00169 // stuff you own, and you can never take away the right to transfer
00170 // something you cannot otherwise copy.
00171 void LLPermissions::fixFairUse()
00172 {
00173         mMaskBase |= PERM_MOVE;
00174         if(!(mMaskBase & PERM_COPY))
00175         {
00176                 mMaskBase |= PERM_TRANSFER;
00177         }
00178         // (mask next owner == PERM_NONE) iff mask base is no transfer
00179         if(mMaskNextOwner != PERM_NONE)
00180         {
00181                 mMaskNextOwner |= PERM_MOVE;
00182         }
00183 }
00184 
00185 void LLPermissions::fixOwnership()
00186 {
00187         if(mOwner.isNull() && mGroup.notNull())
00188         {
00189                 mIsGroupOwned = true;
00190         }
00191         else
00192         {
00193                 mIsGroupOwned = false;
00194         }
00195 }
00196 
00197 // Allow accumulation of permissions. Results in the tightest
00198 // permissions possible. In the case of clashing UUIDs, it sets the ID
00199 // to LLUUID::null.
00200 void LLPermissions::accumulate(const LLPermissions& perm)
00201 {
00202         if(perm.mCreator != mCreator)
00203         {
00204                 mCreator = LLUUID::null;
00205         }
00206         if(perm.mOwner != mOwner)
00207         {
00208                 mOwner = LLUUID::null;
00209         }
00210         if(perm.mLastOwner != mLastOwner)
00211         {
00212                 mLastOwner = LLUUID::null;
00213         }
00214         if(perm.mGroup != mGroup)
00215         {
00216                 mGroup = LLUUID::null;
00217         }
00218 
00219         mMaskBase &= perm.mMaskBase;
00220         mMaskOwner &= perm.mMaskOwner;
00221         mMaskGroup &= perm.mMaskGroup;
00222         mMaskEveryone &= perm.mMaskEveryone;
00223         mMaskNextOwner &= perm.mMaskNextOwner;
00224         fix();
00225 }
00226 
00227 // saves last owner, sets current owner, and sets the group.  note
00228 // that this function has to more cleverly apply the fair use
00229 // permissions.
00230 BOOL LLPermissions::setOwnerAndGroup(
00231         const LLUUID& agent,
00232         const LLUUID& owner,
00233         const LLUUID& group,
00234         bool is_atomic)
00235 {
00236         BOOL allowed = FALSE;
00237 
00238         if( agent.isNull() || mOwner.isNull()
00239            || ((agent == mOwner) && ((owner == mOwner) || (mMaskOwner & PERM_TRANSFER)) ) )
00240         {
00241                 // ...system can alway set owner
00242                 // ...public objects can be claimed by anyone
00243                 // ...otherwise, agent must own it and have transfer ability
00244                 allowed = TRUE;
00245         }
00246 
00247         if (allowed)
00248         {
00249                 if(mLastOwner.isNull() || (!mOwner.isNull() && (owner != mLastOwner)))
00250                 {
00251                         mLastOwner = mOwner;
00252                 }
00253                 if((mOwner != owner)
00254                    || (mOwner.isNull() && owner.isNull() && (mGroup != group)))
00255                 {
00256                         mMaskBase = mMaskNextOwner;
00257                         mOwner = owner;
00258                         // this is a selective use of fair use for atomic
00259                         // permissions.
00260                         if(is_atomic && !(mMaskBase & PERM_COPY))
00261                         {
00262                                 mMaskBase |= PERM_TRANSFER;
00263                         }
00264                 }
00265                 mGroup = group;
00266                 fixOwnership();
00267                 // if it's not atomic and we fix fair use, it blows away
00268                 //objects as inventory items which have different permissions
00269                 //than it's contents. :(
00270                 // fixFairUse();
00271                 mMaskBase |= PERM_MOVE;
00272                 if(mMaskNextOwner != PERM_NONE) mMaskNextOwner |= PERM_MOVE;
00273                 fix();
00274         }
00275 
00276         return allowed;
00277 }
00278 
00279 BOOL LLPermissions::deedToGroup(const LLUUID& agent, const LLUUID& group)
00280 {
00281         if(group.notNull() && (agent.isNull() || ((group == mGroup)
00282                                                                                           && (mMaskOwner & PERM_TRANSFER)
00283                                                                                           && (mMaskGroup & PERM_MOVE))))
00284         {
00285                 if(mOwner.notNull())
00286                 {
00287                         mLastOwner = mOwner;
00288                         mOwner.setNull();
00289                 }
00290                 mMaskBase = mMaskNextOwner;
00291                 mMaskGroup = PERM_NONE;
00292                 mGroup = group;
00293                 mIsGroupOwned = true;
00294                 fixFairUse();
00295                 fix();
00296                 return TRUE;
00297         }
00298         return FALSE;
00299 }
00300 
00301 BOOL LLPermissions::setBaseBits(const LLUUID& agent, BOOL set, PermissionMask bits)
00302 {
00303         BOOL ownership = FALSE;
00304         if(agent.isNull())
00305         {
00306                 // only the system is always allowed to change base bits
00307                 ownership = TRUE;
00308         }
00309 
00310         if (ownership)
00311         {
00312                 if (set)
00313                 {
00314                         mMaskBase |= bits;              // turn on bits
00315                 }
00316                 else
00317                 {
00318                         mMaskBase &= ~bits;             // turn off bits
00319                 }
00320                 fix();
00321         }
00322 
00323         return ownership;
00324 }
00325 
00326 
00327 // Note: If you attempt to set bits that the base bits doesn't allow,
00328 // the function will succeed, but those bits will not be set.
00329 BOOL LLPermissions::setOwnerBits(const LLUUID& agent, BOOL set, PermissionMask bits)
00330 {
00331         BOOL ownership = FALSE;
00332 
00333         if(agent.isNull())
00334         {
00335                 // ...system always allowed to change things
00336                 ownership = TRUE;
00337         }
00338         else if (agent == mOwner)
00339         {
00340                 // ...owner bits can only be set by owner
00341                 ownership = TRUE;
00342         }
00343 
00344         // If we have correct ownership and 
00345         if (ownership)
00346         {
00347                 if (set)
00348                 {
00349                         mMaskOwner |= bits;                     // turn on bits
00350                 }
00351                 else
00352                 {
00353                         mMaskOwner &= ~bits;            // turn off bits
00354                 }
00355                 fix();
00356         }
00357 
00358         return (ownership);
00359 }
00360 
00361 BOOL LLPermissions::setGroupBits(const LLUUID& agent, const LLUUID& group, BOOL set, PermissionMask bits)
00362 {
00363         BOOL ownership = FALSE;
00364         if((agent.isNull()) || (agent == mOwner)
00365            || ((group == mGroup) && (!mGroup.isNull())))
00366         {
00367                 // The group bits can be set by the system, the owner, or a
00368                 // group member.
00369                 ownership = TRUE;
00370         }
00371 
00372         if (ownership)
00373         {
00374                 if (set)
00375                 {
00376                         mMaskGroup |= bits;
00377                 }
00378                 else
00379                 {
00380                         mMaskGroup &= ~bits;
00381                 }
00382                 fix();
00383         }
00384         return ownership;
00385 }
00386 
00387 
00388 // Note: If you attempt to set bits that the creator or owner doesn't allow,
00389 // the function will succeed, but those bits will not be set.
00390 BOOL LLPermissions::setEveryoneBits(const LLUUID& agent, const LLUUID& group, BOOL set, PermissionMask bits)
00391 {
00392         BOOL ownership = FALSE;
00393         if((agent.isNull()) || (agent == mOwner)
00394            || ((group == mGroup) && (!mGroup.isNull())))
00395         {
00396                 // The everyone bits can be set by the system, the owner, or a
00397                 // group member.
00398                 ownership = TRUE;
00399         }
00400         if (ownership)
00401         {
00402                 if (set)
00403                 {
00404                         mMaskEveryone |= bits;
00405                 }
00406                 else
00407                 {
00408                         mMaskEveryone &= ~bits;
00409                 }
00410 
00411                 // Fix hierarchy of permissions
00412                 fix();
00413         }
00414         return ownership;
00415 }
00416 
00417 // Note: If you attempt to set bits that the creator or owner doesn't allow,
00418 // the function will succeed, but those bits will not be set.
00419 BOOL LLPermissions::setNextOwnerBits(const LLUUID& agent, const LLUUID& group, BOOL set, PermissionMask bits)
00420 {
00421         BOOL ownership = FALSE;
00422         if((agent.isNull()) || (agent == mOwner)
00423            || ((group == mGroup) && (!mGroup.isNull())))
00424         {
00425                 // The next owner bits can be set by the system, the owner, or
00426                 // a group member.
00427                 ownership = TRUE;
00428         }
00429         if (ownership)
00430         {
00431                 if (set)
00432                 {
00433                         mMaskNextOwner |= bits;
00434                 }
00435                 else
00436                 {
00437                         mMaskNextOwner &= ~bits;
00438                 }
00439 
00440                 // Fix-up permissions
00441                 if(!(mMaskNextOwner & PERM_COPY))
00442                 {
00443                         mMaskNextOwner |= PERM_TRANSFER;
00444                 }
00445                 fix();
00446         }
00447         return ownership;
00448 }
00449 
00450 BOOL LLPermissions::allowOperationBy(PermissionBit op, const LLUUID& requester, const LLUUID& group) const
00451 {
00452         if(requester.isNull())
00453         {
00454                 // ...system making request
00455                 // ...not owned
00456                 return TRUE;
00457         }
00458         else if (mIsGroupOwned && (mGroup == requester))
00459         {
00460                 // group checking ownership permissions
00461                 return (mMaskOwner & op);
00462         }
00463         else if (!mIsGroupOwned && (mOwner == requester))
00464         {
00465                 // ...owner making request
00466                 return (mMaskOwner & op);
00467         }
00468         else if(mGroup.notNull() && (mGroup == group))
00469         {
00470                 // group member making request
00471                 return ((mMaskGroup & op) || (mMaskEveryone & op));
00472         }
00473         return (mMaskEveryone & op);
00474 }
00475 
00476 //
00477 // LLSD support for HTTP messages.
00478 //
00479 LLSD LLPermissions::packMessage() const
00480 {
00481         LLSD result;
00482         result["creator-id"]    = mCreator;
00483         result["owner-id"]              = mOwner;
00484         result["group-id"]              = mGroup;
00485 
00486         result["base-mask"]             =       (S32)mMaskBase;
00487         result["owner-mask"]    =       (S32)mMaskOwner;
00488         result["group-mask"]    =       (S32)mMaskGroup;
00489         result["everyone-mask"] =       (S32)mMaskEveryone;
00490         result["next-owner-mask"]=      (S32)mMaskNextOwner;
00491         result["group-owned"]   = (BOOL)mIsGroupOwned;
00492         return result;
00493 }
00494 
00495 //
00496 // Messaging support
00497 //
00498 void LLPermissions::packMessage(LLMessageSystem* msg) const
00499 {
00500         msg->addUUIDFast(_PREHASH_CreatorID, mCreator);
00501         msg->addUUIDFast(_PREHASH_OwnerID, mOwner);
00502         msg->addUUIDFast(_PREHASH_GroupID, mGroup);
00503 
00504         msg->addU32Fast(_PREHASH_BaseMask,              mMaskBase );
00505         msg->addU32Fast(_PREHASH_OwnerMask,     mMaskOwner );
00506         msg->addU32Fast(_PREHASH_GroupMask,     mMaskGroup );
00507         msg->addU32Fast(_PREHASH_EveryoneMask,  mMaskEveryone );
00508         msg->addU32Fast(_PREHASH_NextOwnerMask, mMaskNextOwner );
00509         msg->addBOOLFast(_PREHASH_GroupOwned, (BOOL)mIsGroupOwned);
00510 }
00511 
00512 void LLPermissions::unpackMessage(LLSD perms)
00513 {
00514         mCreator        =       perms["creator-id"];
00515         mOwner  =       perms["owner-id"];
00516         mGroup  =       perms["group-id"];
00517 
00518         mMaskBase       =       (U32)perms["base-mask"].asInteger();
00519         mMaskOwner      =       (U32)perms["owner-mask"].asInteger();
00520         mMaskGroup      =       (U32)perms["group-mask"].asInteger();
00521         mMaskEveryone   =       (U32)perms["everyone-mask"].asInteger();
00522         mMaskNextOwner  =       (U32)perms["next-owner-mask"].asInteger();
00523         mIsGroupOwned   =       perms["group-owned"].asBoolean();
00524 }
00525 
00526 void LLPermissions::unpackMessage(LLMessageSystem* msg, const char* block, S32 block_num)
00527 {
00528         msg->getUUIDFast(block, _PREHASH_CreatorID,     mCreator, block_num);
00529         msg->getUUIDFast(block, _PREHASH_OwnerID,       mOwner, block_num);
00530         msg->getUUIDFast(block, _PREHASH_GroupID,       mGroup, block_num);
00531 
00532         msg->getU32Fast(block, _PREHASH_BaseMask, mMaskBase, block_num );
00533         msg->getU32Fast(block, _PREHASH_OwnerMask, mMaskOwner, block_num );
00534         msg->getU32Fast(block, _PREHASH_GroupMask, mMaskGroup, block_num );
00535         msg->getU32Fast(block, _PREHASH_EveryoneMask, mMaskEveryone, block_num );
00536         msg->getU32Fast(block, _PREHASH_NextOwnerMask, mMaskNextOwner, block_num );
00537         BOOL tmp;
00538         msg->getBOOLFast(block, _PREHASH_GroupOwned, tmp, block_num);
00539         mIsGroupOwned = (bool)tmp;
00540 }
00541 
00542 
00543 //
00544 // File support
00545 //
00546 
00547 BOOL LLPermissions::importFile(LLFILE* fp)
00548 {
00549         init(LLUUID::null, LLUUID::null, LLUUID::null, LLUUID::null);
00550         const S32 BUFSIZE = 16384;
00551 
00552         // *NOTE: Changing the buffer size will require changing the scanf
00553         // calls below.
00554         char buffer[BUFSIZE];   /* Flawfinder: ignore */
00555         char keyword[256];      /* Flawfinder: ignore */
00556         char valuestr[256];     /* Flawfinder: ignore */
00557         char uuid_str[256];     /* Flawfinder: ignore */
00558         U32 mask;
00559 
00560         keyword[0]  = '\0';
00561         valuestr[0] = '\0';
00562 
00563         while (!feof(fp))
00564         {
00565                 if (fgets(buffer, BUFSIZE, fp) == NULL)
00566                 {
00567                         buffer[0] = '\0';
00568                 }
00569                 
00570                 sscanf( /* Flawfinder: ignore */
00571                         buffer,
00572                         " %255s %255s",
00573                         keyword, valuestr);
00574                 if (!strcmp("{", keyword))
00575                 {
00576                         continue;
00577                 }
00578                 if (!strcmp("}",keyword))
00579                 {
00580                         break;
00581                 }
00582                 else if (!strcmp("creator_mask", keyword))
00583                 {
00584                         // legacy support for "creator" masks
00585                         sscanf(valuestr, "%x", &mask);
00586                         mMaskBase = mask;
00587                         fixFairUse();
00588                 }
00589                 else if (!strcmp("base_mask", keyword))
00590                 {
00591                         sscanf(valuestr, "%x", &mask);
00592                         mMaskBase = mask;
00593                         //fixFairUse();
00594                 }
00595                 else if (!strcmp("owner_mask", keyword))
00596                 {
00597                         sscanf(valuestr, "%x", &mask);
00598                         mMaskOwner = mask;
00599                 }
00600                 else if (!strcmp("group_mask", keyword))
00601                 {
00602                         sscanf(valuestr, "%x", &mask);
00603                         mMaskGroup = mask;
00604                 }
00605                 else if (!strcmp("everyone_mask", keyword))
00606                 {
00607                         sscanf(valuestr, "%x", &mask);
00608                         mMaskEveryone = mask;
00609                 }
00610                 else if (!strcmp("next_owner_mask", keyword))
00611                 {
00612                         sscanf(valuestr, "%x", &mask);
00613                         mMaskNextOwner = mask;
00614                 }
00615                 else if (!strcmp("creator_id", keyword))
00616                 {
00617                         sscanf(valuestr, "%255s", uuid_str); /* Flawfinder: ignore */
00618                         mCreator.set(uuid_str);
00619                 }
00620                 else if (!strcmp("owner_id", keyword))
00621                 {
00622                         sscanf(valuestr, "%255s", uuid_str); /* Flawfinder: ignore */
00623                         mOwner.set(uuid_str);
00624                 }
00625                 else if (!strcmp("last_owner_id", keyword))
00626                 {
00627                         sscanf(valuestr, "%255s", uuid_str); /* Flawfinder: ignore */
00628                         mLastOwner.set(uuid_str);
00629                 }
00630                 else if (!strcmp("group_id", keyword))
00631                 {
00632                         sscanf(valuestr, "%255s", uuid_str); /* Flawfinder: ignore */
00633                         mGroup.set(uuid_str);
00634                 }
00635                 else if (!strcmp("group_owned", keyword))
00636                 {
00637                         sscanf(valuestr, "%d", &mask);
00638                         if(mask) mIsGroupOwned = true;
00639                         else mIsGroupOwned = false;
00640                 }
00641                 else
00642                 {
00643                         llinfos << "unknown keyword " << keyword << " in permissions import" << llendl;
00644                 }
00645         }
00646         fix();
00647         return TRUE;
00648 }
00649 
00650 
00651 BOOL LLPermissions::exportFile(LLFILE* fp) const
00652 {
00653         char uuid_str[256];     /* Flawfinder: ignore */
00654 
00655         fprintf(fp, "\tpermissions 0\n");
00656         fprintf(fp, "\t{\n");
00657 
00658         fprintf(fp, "\t\tbase_mask\t%08x\n",            mMaskBase);
00659         fprintf(fp, "\t\towner_mask\t%08x\n",           mMaskOwner);
00660         fprintf(fp, "\t\tgroup_mask\t%08x\n",           mMaskGroup);
00661         fprintf(fp, "\t\teveryone_mask\t%08x\n",        mMaskEveryone);
00662         fprintf(fp, "\t\tnext_owner_mask\t%08x\n",      mMaskNextOwner);
00663 
00664         mCreator.toString(uuid_str);
00665         fprintf(fp, "\t\tcreator_id\t%s\n",                     uuid_str);
00666 
00667         mOwner.toString(uuid_str);
00668         fprintf(fp, "\t\towner_id\t%s\n",                       uuid_str);
00669 
00670         mLastOwner.toString(uuid_str);
00671         fprintf(fp, "\t\tlast_owner_id\t%s\n",          uuid_str);
00672 
00673         mGroup.toString(uuid_str);
00674         fprintf(fp, "\t\tgroup_id\t%s\n",                       uuid_str);
00675 
00676         if(mIsGroupOwned)
00677         {
00678                 fprintf(fp, "\t\tgroup_owned\t1\n");
00679         }
00680         fprintf(fp,"\t}\n");
00681         return TRUE;
00682 }
00683 
00684 
00685 BOOL LLPermissions::importLegacyStream(std::istream& input_stream)
00686 {
00687         init(LLUUID::null, LLUUID::null, LLUUID::null, LLUUID::null);
00688         const S32 BUFSIZE = 16384;
00689 
00690         // *NOTE: Changing the buffer size will require changing the scanf
00691         // calls below.
00692         char buffer[BUFSIZE];   /* Flawfinder: ignore */
00693         char keyword[256];      /* Flawfinder: ignore */
00694         char valuestr[256];     /* Flawfinder: ignore */
00695         char uuid_str[256];     /* Flawfinder: ignore */
00696         U32 mask;
00697 
00698         keyword[0]  = '\0';
00699         valuestr[0] = '\0';
00700 
00701         while (input_stream.good())
00702         {
00703                 input_stream.getline(buffer, BUFSIZE);
00704                 sscanf( /* Flawfinder: ignore */
00705                         buffer,
00706                         " %255s %255s",
00707                         keyword, valuestr);
00708                 if (!strcmp("{", keyword))
00709                 {
00710                         continue;
00711                 }
00712                 if (!strcmp("}",keyword))
00713                 {
00714                         break;
00715                 }
00716                 else if (!strcmp("creator_mask", keyword))
00717                 {
00718                         // legacy support for "creator" masks
00719                         sscanf(valuestr, "%x", &mask);
00720                         mMaskBase = mask;
00721                         fixFairUse();
00722                 }
00723                 else if (!strcmp("base_mask", keyword))
00724                 {
00725                         sscanf(valuestr, "%x", &mask);
00726                         mMaskBase = mask;
00727                         //fixFairUse();
00728                 }
00729                 else if (!strcmp("owner_mask", keyword))
00730                 {
00731                         sscanf(valuestr, "%x", &mask);
00732                         mMaskOwner = mask;
00733                 }
00734                 else if (!strcmp("group_mask", keyword))
00735                 {
00736                         sscanf(valuestr, "%x", &mask);
00737                         mMaskGroup = mask;
00738                 }
00739                 else if (!strcmp("everyone_mask", keyword))
00740                 {
00741                         sscanf(valuestr, "%x", &mask);
00742                         mMaskEveryone = mask;
00743                 }
00744                 else if (!strcmp("next_owner_mask", keyword))
00745                 {
00746                         sscanf(valuestr, "%x", &mask);
00747                         mMaskNextOwner = mask;
00748                 }
00749                 else if (!strcmp("creator_id", keyword))
00750                 {
00751                         sscanf(valuestr, "%255s", uuid_str);    /* Flawfinder: ignore */
00752                         mCreator.set(uuid_str);
00753                 }
00754                 else if (!strcmp("owner_id", keyword))
00755                 {
00756                         sscanf(valuestr, "%255s", uuid_str);    /* Flawfinder: ignore */
00757                         mOwner.set(uuid_str);
00758                 }
00759                 else if (!strcmp("last_owner_id", keyword))
00760                 {
00761                         sscanf(valuestr, "%255s", uuid_str);    /* Flawfinder: ignore */
00762                         mLastOwner.set(uuid_str);
00763                 }
00764                 else if (!strcmp("group_id", keyword))
00765                 {
00766                         sscanf(valuestr, "%255s", uuid_str);    /* Flawfinder: ignore */
00767                         mGroup.set(uuid_str);
00768                 }
00769                 else if (!strcmp("group_owned", keyword))
00770                 {
00771                         sscanf(valuestr, "%d", &mask);
00772                         if(mask) mIsGroupOwned = true;
00773                         else mIsGroupOwned = false;
00774                 }
00775                 else
00776                 {
00777                         llinfos << "unknown keyword " << keyword << " in permissions import" << llendl;
00778                 }
00779         }
00780         fix();
00781         return TRUE;
00782 }
00783 
00784 
00785 BOOL LLPermissions::exportLegacyStream(std::ostream& output_stream) const
00786 {
00787         char uuid_str[256];     /* Flawfinder: ignore */
00788 
00789         output_stream <<  "\tpermissions 0\n";
00790         output_stream <<  "\t{\n";
00791 
00792         char buffer[256];       /* Flawfinder: ignore */
00793         snprintf(buffer, sizeof(buffer), "\t\tbase_mask\t%08x\n",               mMaskBase);             /* Flawfinder: ignore */
00794         output_stream << buffer;
00795         snprintf(buffer, sizeof(buffer), "\t\towner_mask\t%08x\n",              mMaskOwner);            /* Flawfinder: ignore */
00796         output_stream << buffer;
00797         snprintf(buffer, sizeof(buffer), "\t\tgroup_mask\t%08x\n",              mMaskGroup);            /* Flawfinder: ignore */
00798         output_stream << buffer;
00799         snprintf(buffer, sizeof(buffer), "\t\teveryone_mask\t%08x\n",   mMaskEveryone);         /* Flawfinder: ignore */
00800         output_stream << buffer;
00801         snprintf(buffer, sizeof(buffer), "\t\tnext_owner_mask\t%08x\n", mMaskNextOwner);                /* Flawfinder: ignore */
00802         output_stream << buffer;
00803 
00804         mCreator.toString(uuid_str);
00805         output_stream <<  "\t\tcreator_id\t" << uuid_str << "\n";
00806 
00807         mOwner.toString(uuid_str);
00808         output_stream <<  "\t\towner_id\t" << uuid_str << "\n";
00809 
00810         mLastOwner.toString(uuid_str);
00811         output_stream <<  "\t\tlast_owner_id\t" << uuid_str << "\n";
00812 
00813         mGroup.toString(uuid_str);
00814         output_stream <<  "\t\tgroup_id\t" << uuid_str << "\n";
00815 
00816         if(mIsGroupOwned)
00817         {
00818                 output_stream <<  "\t\tgroup_owned\t1\n";
00819         }
00820         output_stream << "\t}\n";
00821         return TRUE;
00822 }
00823 
00824 
00825 LLXMLNode *LLPermissions::exportFileXML() const
00826 {
00827         LLXMLNode *ret = new LLXMLNode("permissions", FALSE);
00828 
00829         ret->createChild("group_owned", TRUE)->setBoolValue(1, (const BOOL*)&mIsGroupOwned);
00830 
00831         ret->createChild("base_mask", FALSE)->setByteValue(4, (U8*)&mMaskBase, LLXMLNode::ENCODING_HEX);
00832         ret->createChild("owner_mask", FALSE)->setByteValue(4, (U8*)&mMaskOwner, LLXMLNode::ENCODING_HEX);
00833         ret->createChild("group_mask", FALSE)->setByteValue(4, (U8*)&mMaskGroup, LLXMLNode::ENCODING_HEX);
00834         ret->createChild("everyone_mask", FALSE)->setByteValue(4, (U8*)&mMaskEveryone, LLXMLNode::ENCODING_HEX);
00835         ret->createChild("next_owner_mask", FALSE)->setByteValue(4, (U8*)&mMaskNextOwner, LLXMLNode::ENCODING_HEX);
00836 
00837         ret->createChild("creator_id", FALSE)->setUUIDValue(1, &mCreator);
00838         ret->createChild("owner_id", FALSE)->setUUIDValue(1, &mOwner);
00839         ret->createChild("last_owner_id", FALSE)->setUUIDValue(1, &mLastOwner);
00840         ret->createChild("group_id", FALSE)->setUUIDValue(1, &mGroup);
00841 
00842         return ret;
00843 }
00844 
00845 bool LLPermissions::importXML(LLXMLNode* node)
00846 {
00847         bool success = false;
00848         if (node)
00849         {
00850                 success = true;
00851                 LLXMLNodePtr sub_node;
00852                 if (node->getChild("base_mask", sub_node))
00853                         success = success && (4 == sub_node->getByteValue(4, (U8*)&mMaskBase));
00854                 if (node->getChild("owner_mask", sub_node))
00855                         success = success && (4 == sub_node->getByteValue(4, (U8*)&mMaskOwner));
00856                 if (node->getChild("group_mask", sub_node))
00857                         success = success && (4 == sub_node->getByteValue(4, (U8*)&mMaskGroup));
00858                 if (node->getChild("everyone_mask", sub_node))
00859                         success = success && (4 == sub_node->getByteValue(4, (U8*)&mMaskEveryone));
00860                 if (node->getChild("next_owner_mask", sub_node))
00861                         success = success && (4 == sub_node->getByteValue(4, (U8*)&mMaskNextOwner));
00862 
00863                 if (node->getChild("creator_id", sub_node))
00864                         success = success && (1 == sub_node->getUUIDValue(1, &mCreator));
00865                 if (node->getChild("owner_id", sub_node))
00866                         success = success && (1 == sub_node->getUUIDValue(1, &mOwner));
00867                 if (node->getChild("last_owner_id", sub_node))
00868                         success = success && (1 == sub_node->getUUIDValue(1, &mLastOwner));
00869                 if (node->getChild("group_id", sub_node))
00870                         success = success && (1 == sub_node->getUUIDValue(1, &mGroup));
00871                 if (node->getChild("group_owned", sub_node))
00872                         success = success && (1 == sub_node->getBoolValue(1, (BOOL*)&mIsGroupOwned));
00873                 if (!success)
00874                 {
00875                         lldebugs << "LLPermissions::importXML() failed for node named '" 
00876                                 << node->getName() << "'" << llendl;
00877                 }
00878         }
00879         return success;
00880 }
00881 
00882 bool LLPermissions::operator==(const LLPermissions &rhs) const
00883 {   
00884         return 
00885                 (mCreator == rhs.mCreator) &&
00886                 (mOwner == rhs.mOwner) &&
00887                 (mLastOwner == rhs.mLastOwner ) &&
00888                 (mGroup == rhs.mGroup ) &&
00889                 (mMaskBase == rhs.mMaskBase ) &&
00890                 (mMaskOwner == rhs.mMaskOwner ) &&
00891                 (mMaskGroup == rhs.mMaskGroup ) &&
00892                 (mMaskEveryone == rhs.mMaskEveryone ) &&
00893                 (mMaskNextOwner == rhs.mMaskNextOwner ) &&
00894                 (mIsGroupOwned == rhs.mIsGroupOwned);
00895 }
00896 
00897 
00898 bool LLPermissions::operator!=(const LLPermissions &rhs) const
00899 {   
00900         return 
00901                 (mCreator != rhs.mCreator) ||
00902                 (mOwner != rhs.mOwner) ||
00903                 (mLastOwner != rhs.mLastOwner ) ||
00904                 (mGroup != rhs.mGroup ) ||
00905                 (mMaskBase != rhs.mMaskBase ) ||
00906                 (mMaskOwner != rhs.mMaskOwner ) ||
00907                 (mMaskGroup != rhs.mMaskGroup ) ||
00908                 (mMaskEveryone != rhs.mMaskEveryone ) ||
00909                 (mMaskNextOwner != rhs.mMaskNextOwner) ||
00910                 (mIsGroupOwned != rhs.mIsGroupOwned);
00911 }
00912 
00913 std::ostream& operator<<(std::ostream &s, const LLPermissions &perm)
00914 {
00915         s << "{Creator="                << perm.getCreator();
00916         s << ", Owner="                 << perm.getOwner();
00917         s << ", Group="                 << perm.getGroup();
00918         s << std::hex << ", BaseMask=0x" << perm.getMaskBase();
00919         s << ", OwnerMask=0x" << perm.getMaskOwner();
00920         s << ", EveryoneMask=0x" << perm.getMaskEveryone();
00921         s << ", GroupMask=0x" << perm.getMaskGroup();
00922         s << ", NextOwnerMask=0x" << perm.getMaskNextOwner() << std::dec;
00923         s << "}";
00924         return s;
00925 }
00926 
00927 template <>
00928 void LLMetaClassT<LLPermissions>::reflectProperties(LLMetaClass& meta_class)
00929 {
00930         reflectProperty(meta_class, "mCreator", &LLPermissions::mCreator);
00931         reflectProperty(meta_class, "mOwner", &LLPermissions::mOwner);
00932 }
00933 
00934 // virtual
00935 const LLMetaClass& LLPermissions::getMetaClass() const
00936 {
00937         return LLMetaClassT<LLPermissions>::instance();
00938 }
00939 
00943 
00944 const LLAggregatePermissions LLAggregatePermissions::empty;
00945 
00946 
00947 LLAggregatePermissions::LLAggregatePermissions()
00948 {
00949         for(S32 i = 0; i < PI_COUNT; ++i)
00950         {
00951                 mBits[i] = AP_EMPTY;
00952         }
00953 }
00954 
00955 LLAggregatePermissions::EValue LLAggregatePermissions::getValue(PermissionBit bit) const
00956 {
00957         EPermIndex idx = perm2PermIndex(bit);
00958         EValue rv = AP_EMPTY;
00959         if(idx != PI_END)
00960         {
00961                 rv = (LLAggregatePermissions::EValue)(mBits[idx]);
00962         }
00963         return rv;
00964 }
00965 
00966 // returns the bits compressed into a single byte: 00TTMMCC
00967 // where TT = transfer, MM = modify, and CC = copy
00968 // LSB is to the right
00969 U8 LLAggregatePermissions::getU8() const
00970 {
00971         U8 byte = mBits[PI_TRANSFER];
00972         byte <<= 2;
00973         byte |= mBits[PI_MODIFY];
00974         byte <<= 2;
00975         byte |= mBits[PI_COPY];
00976         return byte;
00977 }
00978 
00979 BOOL LLAggregatePermissions::isEmpty() const
00980 {
00981         for(S32 i = 0; i < PI_END; ++i)
00982         {
00983                 if(mBits[i] != AP_EMPTY)
00984                 {
00985                         return FALSE;
00986                 }
00987         }
00988         return TRUE;
00989 }
00990 
00991 void LLAggregatePermissions::aggregate(PermissionMask mask)
00992 {
00993         BOOL is_allowed = mask & PERM_COPY;
00994         aggregateBit(PI_COPY, is_allowed);
00995         is_allowed = mask & PERM_MODIFY;
00996         aggregateBit(PI_MODIFY, is_allowed);
00997         is_allowed = mask & PERM_TRANSFER;
00998         aggregateBit(PI_TRANSFER, is_allowed);
00999 }
01000 
01001 void LLAggregatePermissions::aggregate(const LLAggregatePermissions& ag)
01002 {
01003         for(S32 idx = PI_COPY; idx != PI_END; ++idx)
01004         {
01005                 aggregateIndex((EPermIndex)idx, ag.mBits[idx]);
01006         }
01007 }
01008 
01009 void LLAggregatePermissions::aggregateBit(EPermIndex idx, BOOL allowed)
01010 {
01011         //if(AP_SOME == mBits[idx]) return; // P4 branch prediction optimization
01012         switch(mBits[idx])
01013         {
01014         case AP_EMPTY:
01015                 mBits[idx] = allowed ? AP_ALL : AP_NONE;
01016                 break;
01017         case AP_NONE:
01018                 mBits[idx] = allowed ? AP_SOME: AP_NONE;
01019                 break;
01020         case AP_SOME:
01021                 // no-op
01022                 break;
01023         case AP_ALL:
01024                 mBits[idx] = allowed ? AP_ALL : AP_SOME;
01025                 break;
01026         default:
01027                 llwarns << "Bad aggregateBit " << (S32)idx << " "
01028                                 << (allowed ? "true" : "false") << llendl;
01029                 break;
01030         }
01031 }
01032 
01033 void LLAggregatePermissions::aggregateIndex(EPermIndex idx, U8 bits)
01034 {
01035         switch(mBits[idx])
01036         {
01037         case AP_EMPTY:
01038                 mBits[idx] = bits;
01039                 break;
01040         case AP_NONE:
01041                 switch(bits)
01042                 {
01043                 case AP_SOME:
01044                 case AP_ALL:
01045                         mBits[idx] = AP_SOME;
01046                         break;
01047                 case AP_EMPTY:
01048                 case AP_NONE:
01049                 default:
01050                         // no-op
01051                         break;
01052                 }
01053                 break;
01054         case AP_SOME:
01055                 // no-op
01056                 break;
01057         case AP_ALL:
01058                 switch(bits)
01059                 {
01060                 case AP_NONE:
01061                 case AP_SOME:
01062                         mBits[idx] = AP_SOME;
01063                         break;
01064                 case AP_EMPTY:
01065                 case AP_ALL:
01066                 default:
01067                         // no-op
01068                         break;
01069                 }
01070                 break;
01071         default:
01072                 llwarns << "Bad aggregate index " << (S32)idx << " "
01073                                 <<  (S32)bits << llendl;
01074                 break;
01075         }
01076 }
01077 
01078 // static
01079 LLAggregatePermissions::EPermIndex LLAggregatePermissions::perm2PermIndex(PermissionBit bit)
01080 {
01081         EPermIndex idx = PI_END; // past any good value.
01082         switch(bit)
01083         {
01084         case PERM_COPY:
01085                 idx = PI_COPY;
01086                 break;
01087         case PERM_MODIFY:
01088                 idx = PI_MODIFY;
01089                 break;
01090         case PERM_TRANSFER:
01091                 idx = PI_TRANSFER;
01092                 break;
01093         default:
01094                 break;
01095         }
01096         return idx;
01097 }
01098 
01099 
01100 void LLAggregatePermissions::packMessage(LLMessageSystem* msg, const char* field) const
01101 {
01102         msg->addU8Fast(field, getU8());
01103 }
01104 
01105 void LLAggregatePermissions::unpackMessage(LLMessageSystem* msg, const char* block, const char* field, S32 block_num)
01106 {
01107         const U8 TWO_BITS = 0x3; // binary 00000011
01108         U8 bits = 0;
01109         msg->getU8Fast(block, field, bits, block_num);
01110         mBits[PI_COPY] = bits & TWO_BITS;
01111         bits >>= 2;
01112         mBits[PI_MODIFY] = bits & TWO_BITS;
01113         bits >>= 2;
01114         mBits[PI_TRANSFER] = bits & TWO_BITS;
01115 }
01116 
01117 const LLString AGGREGATE_VALUES[4] =
01118         {
01119                 LLString( "Empty" ),
01120                 LLString( "None" ),
01121                 LLString( "Some" ),
01122                 LLString( "All" )
01123         };
01124 
01125 std::ostream& operator<<(std::ostream &s, const LLAggregatePermissions &perm)
01126 {
01127         s << "{PI_COPY=" << AGGREGATE_VALUES[perm.mBits[LLAggregatePermissions::PI_COPY]];
01128         s << ", PI_MODIFY=" << AGGREGATE_VALUES[perm.mBits[LLAggregatePermissions::PI_MODIFY]];
01129         s << ", PI_TRANSFER=" << AGGREGATE_VALUES[perm.mBits[LLAggregatePermissions::PI_TRANSFER]];
01130         s << "}";
01131         return s;
01132 }
01133 
01134 // This converts a permissions mask into a string for debugging use.
01135 void mask_to_string(U32 mask, char* str)
01136 {
01137         if (mask & PERM_MOVE)
01138         {
01139                 *str = 'V';
01140         }
01141         else
01142         {
01143                 *str = ' ';
01144         }       
01145         str++;
01146 
01147         if (mask & PERM_MODIFY)
01148         {
01149                 *str = 'M';
01150         }
01151         else
01152         {
01153                 *str = ' ';
01154         }       
01155         str++;
01156         
01157         if (mask & PERM_COPY)
01158         {
01159                 *str = 'C';
01160         }
01161         else
01162         {
01163                 *str = ' ';
01164         }       
01165         str++;
01166         
01167         if (mask & PERM_TRANSFER)
01168         {
01169                 *str = 'T';
01170         }
01171         else
01172         {
01173                 *str = ' ';
01174         }       
01175         str++;  
01176         *str = '\0';
01177 }
01178 
01179 std::string mask_to_string(U32 mask)
01180 {
01181         char str[16];
01182         mask_to_string(mask, str);
01183         return std::string(str);
01184 }
01185 
01189 static const std::string PERM_CREATOR_ID_LABEL("creator_id");
01190 static const std::string PERM_OWNER_ID_LABEL("owner_id");
01191 static const std::string PERM_LAST_OWNER_ID_LABEL("last_owner_id");
01192 static const std::string PERM_GROUP_ID_LABEL("group_id");
01193 static const std::string PERM_IS_OWNER_GROUP_LABEL("is_owner_group");
01194 static const std::string PERM_BASE_MASK_LABEL("base_mask");
01195 static const std::string PERM_OWNER_MASK_LABEL("owner_mask");
01196 static const std::string PERM_GROUP_MASK_LABEL("group_mask");
01197 static const std::string PERM_EVERYONE_MASK_LABEL("everyone_mask");
01198 static const std::string PERM_NEXT_OWNER_MASK_LABEL("next_owner_mask");
01199 
01200 LLSD ll_create_sd_from_permissions(const LLPermissions& perm)
01201 {
01202         LLSD rv;
01203         rv[PERM_CREATOR_ID_LABEL] = perm.getCreator();
01204         rv[PERM_OWNER_ID_LABEL] = perm.getOwner();
01205         rv[PERM_LAST_OWNER_ID_LABEL] = perm.getLastOwner();
01206         rv[PERM_GROUP_ID_LABEL] = perm.getGroup();
01207         rv[PERM_IS_OWNER_GROUP_LABEL] = perm.isGroupOwned();
01208         rv[PERM_BASE_MASK_LABEL] = (S32)perm.getMaskBase();
01209         rv[PERM_OWNER_MASK_LABEL] = (S32)perm.getMaskOwner();
01210         rv[PERM_GROUP_MASK_LABEL] = (S32)perm.getMaskGroup();
01211         rv[PERM_EVERYONE_MASK_LABEL] = (S32)perm.getMaskEveryone();
01212         rv[PERM_NEXT_OWNER_MASK_LABEL] = (S32)perm.getMaskNextOwner();
01213         return rv;
01214 }
01215 
01216 LLPermissions ll_permissions_from_sd(const LLSD& sd_perm)
01217 {
01218         LLPermissions rv;
01219         rv.init(
01220                 sd_perm[PERM_CREATOR_ID_LABEL].asUUID(),
01221                 sd_perm[PERM_OWNER_ID_LABEL].asUUID(),
01222                 sd_perm[PERM_LAST_OWNER_ID_LABEL].asUUID(),
01223                 sd_perm[PERM_GROUP_ID_LABEL].asUUID());
01224 
01225         // We do a cast to U32 here since LLSD does not attempt to
01226         // represent unsigned ints.
01227         PermissionMask mask;
01228         mask = (U32)(sd_perm[PERM_BASE_MASK_LABEL].asInteger());
01229         rv.setMaskBase(mask);
01230         mask = (U32)(sd_perm[PERM_OWNER_MASK_LABEL].asInteger());
01231         rv.setMaskOwner(mask);
01232         mask = (U32)(sd_perm[PERM_EVERYONE_MASK_LABEL].asInteger());
01233         rv.setMaskEveryone(mask);
01234         mask = (U32)(sd_perm[PERM_GROUP_MASK_LABEL].asInteger());
01235         rv.setMaskGroup(mask);
01236         mask = (U32)(sd_perm[PERM_NEXT_OWNER_MASK_LABEL].asInteger());
01237         rv.setMaskNext(mask);
01238         rv.fix();
01239         return rv;
01240 }

Generated on Fri May 16 08:32:13 2008 for SecondLife by  doxygen 1.5.5