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

Generated on Thu Jul 1 06:09:00 2010 for Second Life Viewer by  doxygen 1.4.7