/indra/llinventory/llpermissions.cpp

https://bitbucket.org/lindenlab/viewer-beta/ · C++ · 1213 lines · 966 code · 118 blank · 129 comment · 195 complexity · 3b2495c1eda053d032f821d5b1bb5c84 MD5 · raw file

  1. /**
  2. * @file llpermissions.cpp
  3. * @author Phoenix
  4. * @brief Permissions for objects and inventory.
  5. *
  6. * $LicenseInfo:firstyear=2002&license=viewerlgpl$
  7. * Second Life Viewer Source Code
  8. * Copyright (C) 2010, Linden Research, Inc.
  9. *
  10. * This library is free software; you can redistribute it and/or
  11. * modify it under the terms of the GNU Lesser General Public
  12. * License as published by the Free Software Foundation;
  13. * version 2.1 of the License only.
  14. *
  15. * This library is distributed in the hope that it will be useful,
  16. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  18. * Lesser General Public License for more details.
  19. *
  20. * You should have received a copy of the GNU Lesser General Public
  21. * License along with this library; if not, write to the Free Software
  22. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  23. *
  24. * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
  25. * $/LicenseInfo$
  26. */
  27. #include "linden_common.h"
  28. #include "llpermissions.h"
  29. // library includes
  30. #include "message.h"
  31. #include "metapropertyt.h"
  32. #include "llsd.h"
  33. ///----------------------------------------------------------------------------
  34. /// Class LLPermissions
  35. ///----------------------------------------------------------------------------
  36. const LLPermissions LLPermissions::DEFAULT;
  37. // No creator = created by system
  38. LLPermissions::LLPermissions()
  39. {
  40. init(LLUUID::null, LLUUID::null, LLUUID::null, LLUUID::null);
  41. }
  42. // Default to created by system
  43. void LLPermissions::init(const LLUUID& creator, const LLUUID& owner, const LLUUID& last_owner, const LLUUID& group)
  44. {
  45. mCreator = creator;
  46. mOwner = owner;
  47. mLastOwner = last_owner;
  48. mGroup = group;
  49. mMaskBase = PERM_ALL;
  50. mMaskOwner = PERM_ALL;
  51. mMaskEveryone = PERM_ALL;
  52. mMaskGroup = PERM_ALL;
  53. mMaskNextOwner = PERM_ALL;
  54. fixOwnership();
  55. }
  56. void LLPermissions::initMasks(PermissionMask base, PermissionMask owner,
  57. PermissionMask everyone, PermissionMask group,
  58. PermissionMask next)
  59. {
  60. mMaskBase = base;
  61. mMaskOwner = owner;
  62. mMaskEveryone = everyone;
  63. mMaskGroup = group;
  64. mMaskNextOwner = next;
  65. fixFairUse();
  66. fix();
  67. }
  68. // ! BACKWARDS COMPATIBILITY ! Override masks for inventory types that
  69. // no longer can have restricted permissions. This takes care of previous
  70. // version landmarks that could have had no copy/mod/transfer bits set.
  71. void LLPermissions::initMasks(LLInventoryType::EType type)
  72. {
  73. if (LLInventoryType::cannotRestrictPermissions(type))
  74. {
  75. initMasks(PERM_ALL, PERM_ALL, PERM_ALL, PERM_ALL, PERM_ALL);
  76. }
  77. }
  78. BOOL LLPermissions::getOwnership(LLUUID& owner_id, BOOL& is_group_owned) const
  79. {
  80. if(mOwner.notNull())
  81. {
  82. owner_id = mOwner;
  83. is_group_owned = FALSE;
  84. return TRUE;
  85. }
  86. else if(mIsGroupOwned)
  87. {
  88. owner_id = mGroup;
  89. is_group_owned = TRUE;
  90. return TRUE;
  91. }
  92. return FALSE;
  93. }
  94. LLUUID LLPermissions::getSafeOwner() const
  95. {
  96. if(mOwner.notNull())
  97. {
  98. return mOwner;
  99. }
  100. else if(mIsGroupOwned)
  101. {
  102. return mGroup;
  103. }
  104. else
  105. {
  106. llwarns << "LLPermissions::getSafeOwner() called with no valid owner!" << llendl;
  107. LLUUID unused_uuid;
  108. unused_uuid.generate();
  109. return unused_uuid;
  110. }
  111. }
  112. U32 LLPermissions::getCRC32() const
  113. {
  114. U32 rv = mCreator.getCRC32();
  115. rv += mOwner.getCRC32();
  116. rv += mLastOwner.getCRC32();
  117. rv += mGroup.getCRC32();
  118. rv += mMaskBase + mMaskOwner + mMaskEveryone + mMaskGroup;
  119. return rv;
  120. }
  121. void LLPermissions::set(const LLPermissions& from)
  122. {
  123. mCreator = from.mCreator;
  124. mOwner = from.mOwner;
  125. mLastOwner = from.mLastOwner;
  126. mGroup = from.mGroup;
  127. mMaskBase = from.mMaskBase;
  128. mMaskOwner = from.mMaskOwner;
  129. mMaskEveryone = from.mMaskEveryone;
  130. mMaskGroup = from.mMaskGroup;
  131. mMaskNextOwner = from.mMaskNextOwner;
  132. mIsGroupOwned = from.mIsGroupOwned;
  133. }
  134. // Fix hierarchy of permissions.
  135. void LLPermissions::fix()
  136. {
  137. mMaskOwner &= mMaskBase;
  138. mMaskGroup &= mMaskOwner;
  139. // next owner uses base, since you may want to sell locked objects.
  140. mMaskNextOwner &= mMaskBase;
  141. mMaskEveryone &= mMaskOwner;
  142. mMaskEveryone &= ~PERM_MODIFY;
  143. if(!(mMaskBase & PERM_TRANSFER) && !mIsGroupOwned)
  144. {
  145. mMaskGroup &= ~PERM_COPY;
  146. mMaskEveryone &= ~PERM_COPY;
  147. // Do not set mask next owner to too restrictive because if we
  148. // rez an object, it may require an ownership transfer during
  149. // rez, which will note the overly restrictive perms, and then
  150. // fix them to allow fair use, which may be different than the
  151. // original intention.
  152. }
  153. }
  154. // Correct for fair use - you can never take away the right to move
  155. // stuff you own, and you can never take away the right to transfer
  156. // something you cannot otherwise copy.
  157. void LLPermissions::fixFairUse()
  158. {
  159. mMaskBase |= PERM_MOVE;
  160. if(!(mMaskBase & PERM_COPY))
  161. {
  162. mMaskBase |= PERM_TRANSFER;
  163. }
  164. // (mask next owner == PERM_NONE) iff mask base is no transfer
  165. if(mMaskNextOwner != PERM_NONE)
  166. {
  167. mMaskNextOwner |= PERM_MOVE;
  168. }
  169. }
  170. void LLPermissions::fixOwnership()
  171. {
  172. if(mOwner.isNull() && mGroup.notNull())
  173. {
  174. mIsGroupOwned = true;
  175. }
  176. else
  177. {
  178. mIsGroupOwned = false;
  179. }
  180. }
  181. // Allow accumulation of permissions. Results in the tightest
  182. // permissions possible. In the case of clashing UUIDs, it sets the ID
  183. // to LLUUID::null.
  184. void LLPermissions::accumulate(const LLPermissions& perm)
  185. {
  186. if(perm.mCreator != mCreator)
  187. {
  188. mCreator = LLUUID::null;
  189. }
  190. if(perm.mOwner != mOwner)
  191. {
  192. mOwner = LLUUID::null;
  193. }
  194. if(perm.mLastOwner != mLastOwner)
  195. {
  196. mLastOwner = LLUUID::null;
  197. }
  198. if(perm.mGroup != mGroup)
  199. {
  200. mGroup = LLUUID::null;
  201. }
  202. mMaskBase &= perm.mMaskBase;
  203. mMaskOwner &= perm.mMaskOwner;
  204. mMaskGroup &= perm.mMaskGroup;
  205. mMaskEveryone &= perm.mMaskEveryone;
  206. mMaskNextOwner &= perm.mMaskNextOwner;
  207. fix();
  208. }
  209. // saves last owner, sets current owner, and sets the group. note
  210. // that this function has to more cleverly apply the fair use
  211. // permissions.
  212. BOOL LLPermissions::setOwnerAndGroup(
  213. const LLUUID& agent,
  214. const LLUUID& owner,
  215. const LLUUID& group,
  216. bool is_atomic)
  217. {
  218. BOOL allowed = FALSE;
  219. if( agent.isNull() || mOwner.isNull()
  220. || ((agent == mOwner) && ((owner == mOwner) || (mMaskOwner & PERM_TRANSFER)) ) )
  221. {
  222. // ...system can alway set owner
  223. // ...public objects can be claimed by anyone
  224. // ...otherwise, agent must own it and have transfer ability
  225. allowed = TRUE;
  226. }
  227. if (allowed)
  228. {
  229. if(mLastOwner.isNull() || (!mOwner.isNull() && (owner != mLastOwner)))
  230. {
  231. mLastOwner = mOwner;
  232. }
  233. if((mOwner != owner)
  234. || (mOwner.isNull() && owner.isNull() && (mGroup != group)))
  235. {
  236. mMaskBase = mMaskNextOwner;
  237. mOwner = owner;
  238. // this is a selective use of fair use for atomic
  239. // permissions.
  240. if(is_atomic && !(mMaskBase & PERM_COPY))
  241. {
  242. mMaskBase |= PERM_TRANSFER;
  243. }
  244. }
  245. mGroup = group;
  246. fixOwnership();
  247. // if it's not atomic and we fix fair use, it blows away
  248. //objects as inventory items which have different permissions
  249. //than it's contents. :(
  250. // fixFairUse();
  251. mMaskBase |= PERM_MOVE;
  252. if(mMaskNextOwner != PERM_NONE) mMaskNextOwner |= PERM_MOVE;
  253. fix();
  254. }
  255. return allowed;
  256. }
  257. //Fix for DEV-33917, last owner isn't used much and has little impact on
  258. //permissions so it's reasonably safe to do this, however, for now,
  259. //limiting the functionality of this routine to objects which are
  260. //group owned.
  261. void LLPermissions::setLastOwner(const LLUUID& last_owner)
  262. {
  263. if (isGroupOwned())
  264. mLastOwner = last_owner;
  265. }
  266. // only call this if you know what you're doing
  267. // there are usually perm-bit consequences when the
  268. // ownerhsip changes
  269. void LLPermissions::yesReallySetOwner(const LLUUID& owner, bool group_owned)
  270. {
  271. mOwner = owner;
  272. mIsGroupOwned = group_owned;
  273. }
  274. BOOL LLPermissions::deedToGroup(const LLUUID& agent, const LLUUID& group)
  275. {
  276. if(group.notNull() && (agent.isNull() || ((group == mGroup)
  277. && (mMaskOwner & PERM_TRANSFER)
  278. && (mMaskGroup & PERM_MOVE))))
  279. {
  280. if(mOwner.notNull())
  281. {
  282. mLastOwner = mOwner;
  283. mOwner.setNull();
  284. }
  285. mMaskBase = mMaskNextOwner;
  286. mMaskGroup = PERM_NONE;
  287. mGroup = group;
  288. mIsGroupOwned = true;
  289. fixFairUse();
  290. fix();
  291. return TRUE;
  292. }
  293. return FALSE;
  294. }
  295. BOOL LLPermissions::setBaseBits(const LLUUID& agent, BOOL set, PermissionMask bits)
  296. {
  297. BOOL ownership = FALSE;
  298. if(agent.isNull())
  299. {
  300. // only the system is always allowed to change base bits
  301. ownership = TRUE;
  302. }
  303. if (ownership)
  304. {
  305. if (set)
  306. {
  307. mMaskBase |= bits; // turn on bits
  308. }
  309. else
  310. {
  311. mMaskBase &= ~bits; // turn off bits
  312. }
  313. fix();
  314. }
  315. return ownership;
  316. }
  317. // Note: If you attempt to set bits that the base bits doesn't allow,
  318. // the function will succeed, but those bits will not be set.
  319. BOOL LLPermissions::setOwnerBits(const LLUUID& agent, BOOL set, PermissionMask bits)
  320. {
  321. BOOL ownership = FALSE;
  322. if(agent.isNull())
  323. {
  324. // ...system always allowed to change things
  325. ownership = TRUE;
  326. }
  327. else if (agent == mOwner)
  328. {
  329. // ...owner bits can only be set by owner
  330. ownership = TRUE;
  331. }
  332. // If we have correct ownership and
  333. if (ownership)
  334. {
  335. if (set)
  336. {
  337. mMaskOwner |= bits; // turn on bits
  338. }
  339. else
  340. {
  341. mMaskOwner &= ~bits; // turn off bits
  342. }
  343. fix();
  344. }
  345. return (ownership);
  346. }
  347. BOOL LLPermissions::setGroupBits(const LLUUID& agent, const LLUUID& group, BOOL set, PermissionMask bits)
  348. {
  349. BOOL ownership = FALSE;
  350. if((agent.isNull()) || (agent == mOwner)
  351. || ((group == mGroup) && (!mGroup.isNull())))
  352. {
  353. // The group bits can be set by the system, the owner, or a
  354. // group member.
  355. ownership = TRUE;
  356. }
  357. if (ownership)
  358. {
  359. if (set)
  360. {
  361. mMaskGroup |= bits;
  362. }
  363. else
  364. {
  365. mMaskGroup &= ~bits;
  366. }
  367. fix();
  368. }
  369. return ownership;
  370. }
  371. // Note: If you attempt to set bits that the creator or owner doesn't allow,
  372. // the function will succeed, but those bits will not be set.
  373. BOOL LLPermissions::setEveryoneBits(const LLUUID& agent, const LLUUID& group, BOOL set, PermissionMask bits)
  374. {
  375. BOOL ownership = FALSE;
  376. if((agent.isNull()) || (agent == mOwner)
  377. || ((group == mGroup) && (!mGroup.isNull())))
  378. {
  379. // The everyone bits can be set by the system, the owner, or a
  380. // group member.
  381. ownership = TRUE;
  382. }
  383. if (ownership)
  384. {
  385. if (set)
  386. {
  387. mMaskEveryone |= bits;
  388. }
  389. else
  390. {
  391. mMaskEveryone &= ~bits;
  392. }
  393. // Fix hierarchy of permissions
  394. fix();
  395. }
  396. return ownership;
  397. }
  398. // Note: If you attempt to set bits that the creator or owner doesn't allow,
  399. // the function will succeed, but those bits will not be set.
  400. BOOL LLPermissions::setNextOwnerBits(const LLUUID& agent, const LLUUID& group, BOOL set, PermissionMask bits)
  401. {
  402. BOOL ownership = FALSE;
  403. if((agent.isNull()) || (agent == mOwner)
  404. || ((group == mGroup) && (!mGroup.isNull())))
  405. {
  406. // The next owner bits can be set by the system, the owner, or
  407. // a group member.
  408. ownership = TRUE;
  409. }
  410. if (ownership)
  411. {
  412. if (set)
  413. {
  414. mMaskNextOwner |= bits;
  415. }
  416. else
  417. {
  418. mMaskNextOwner &= ~bits;
  419. }
  420. // Fix-up permissions
  421. if(!(mMaskNextOwner & PERM_COPY))
  422. {
  423. mMaskNextOwner |= PERM_TRANSFER;
  424. }
  425. fix();
  426. }
  427. return ownership;
  428. }
  429. bool LLPermissions::allowOperationBy(PermissionBit op, const LLUUID& requester, const LLUUID& group) const
  430. {
  431. if(requester.isNull())
  432. {
  433. // ...system making request
  434. // ...not owned
  435. return TRUE;
  436. }
  437. else if (mIsGroupOwned && (mGroup == requester))
  438. {
  439. // group checking ownership permissions
  440. return (mMaskOwner & op);
  441. }
  442. else if (!mIsGroupOwned && (mOwner == requester))
  443. {
  444. // ...owner making request
  445. return (mMaskOwner & op);
  446. }
  447. else if(mGroup.notNull() && (mGroup == group))
  448. {
  449. // group member making request
  450. return ((mMaskGroup & op) || (mMaskEveryone & op));
  451. }
  452. return (mMaskEveryone & op);
  453. }
  454. //
  455. // LLSD support for HTTP messages.
  456. //
  457. LLSD LLPermissions::packMessage() const
  458. {
  459. LLSD result;
  460. result["creator-id"] = mCreator;
  461. result["owner-id"] = mOwner;
  462. result["group-id"] = mGroup;
  463. result["base-mask"] = (S32)mMaskBase;
  464. result["owner-mask"] = (S32)mMaskOwner;
  465. result["group-mask"] = (S32)mMaskGroup;
  466. result["everyone-mask"] = (S32)mMaskEveryone;
  467. result["next-owner-mask"]= (S32)mMaskNextOwner;
  468. result["group-owned"] = (BOOL)mIsGroupOwned;
  469. return result;
  470. }
  471. //
  472. // Messaging support
  473. //
  474. void LLPermissions::packMessage(LLMessageSystem* msg) const
  475. {
  476. msg->addUUIDFast(_PREHASH_CreatorID, mCreator);
  477. msg->addUUIDFast(_PREHASH_OwnerID, mOwner);
  478. msg->addUUIDFast(_PREHASH_GroupID, mGroup);
  479. msg->addU32Fast(_PREHASH_BaseMask, mMaskBase );
  480. msg->addU32Fast(_PREHASH_OwnerMask, mMaskOwner );
  481. msg->addU32Fast(_PREHASH_GroupMask, mMaskGroup );
  482. msg->addU32Fast(_PREHASH_EveryoneMask, mMaskEveryone );
  483. msg->addU32Fast(_PREHASH_NextOwnerMask, mMaskNextOwner );
  484. msg->addBOOLFast(_PREHASH_GroupOwned, (BOOL)mIsGroupOwned);
  485. }
  486. void LLPermissions::unpackMessage(LLSD perms)
  487. {
  488. mCreator = perms["creator-id"];
  489. mOwner = perms["owner-id"];
  490. mGroup = perms["group-id"];
  491. mMaskBase = (U32)perms["base-mask"].asInteger();
  492. mMaskOwner = (U32)perms["owner-mask"].asInteger();
  493. mMaskGroup = (U32)perms["group-mask"].asInteger();
  494. mMaskEveryone = (U32)perms["everyone-mask"].asInteger();
  495. mMaskNextOwner = (U32)perms["next-owner-mask"].asInteger();
  496. mIsGroupOwned = perms["group-owned"].asBoolean();
  497. }
  498. void LLPermissions::unpackMessage(LLMessageSystem* msg, const char* block, S32 block_num)
  499. {
  500. msg->getUUIDFast(block, _PREHASH_CreatorID, mCreator, block_num);
  501. msg->getUUIDFast(block, _PREHASH_OwnerID, mOwner, block_num);
  502. msg->getUUIDFast(block, _PREHASH_GroupID, mGroup, block_num);
  503. msg->getU32Fast(block, _PREHASH_BaseMask, mMaskBase, block_num );
  504. msg->getU32Fast(block, _PREHASH_OwnerMask, mMaskOwner, block_num );
  505. msg->getU32Fast(block, _PREHASH_GroupMask, mMaskGroup, block_num );
  506. msg->getU32Fast(block, _PREHASH_EveryoneMask, mMaskEveryone, block_num );
  507. msg->getU32Fast(block, _PREHASH_NextOwnerMask, mMaskNextOwner, block_num );
  508. BOOL tmp;
  509. msg->getBOOLFast(block, _PREHASH_GroupOwned, tmp, block_num);
  510. mIsGroupOwned = (bool)tmp;
  511. }
  512. //
  513. // File support
  514. //
  515. BOOL LLPermissions::importFile(LLFILE* fp)
  516. {
  517. init(LLUUID::null, LLUUID::null, LLUUID::null, LLUUID::null);
  518. const S32 BUFSIZE = 16384;
  519. // *NOTE: Changing the buffer size will require changing the scanf
  520. // calls below.
  521. char buffer[BUFSIZE]; /* Flawfinder: ignore */
  522. char keyword[256]; /* Flawfinder: ignore */
  523. char valuestr[256]; /* Flawfinder: ignore */
  524. char uuid_str[256]; /* Flawfinder: ignore */
  525. U32 mask;
  526. keyword[0] = '\0';
  527. valuestr[0] = '\0';
  528. while (!feof(fp))
  529. {
  530. if (fgets(buffer, BUFSIZE, fp) == NULL)
  531. {
  532. buffer[0] = '\0';
  533. }
  534. sscanf( /* Flawfinder: ignore */
  535. buffer,
  536. " %255s %255s",
  537. keyword, valuestr);
  538. if (!strcmp("{", keyword))
  539. {
  540. continue;
  541. }
  542. if (!strcmp("}",keyword))
  543. {
  544. break;
  545. }
  546. else if (!strcmp("creator_mask", keyword))
  547. {
  548. // legacy support for "creator" masks
  549. sscanf(valuestr, "%x", &mask);
  550. mMaskBase = mask;
  551. fixFairUse();
  552. }
  553. else if (!strcmp("base_mask", keyword))
  554. {
  555. sscanf(valuestr, "%x", &mask);
  556. mMaskBase = mask;
  557. //fixFairUse();
  558. }
  559. else if (!strcmp("owner_mask", keyword))
  560. {
  561. sscanf(valuestr, "%x", &mask);
  562. mMaskOwner = mask;
  563. }
  564. else if (!strcmp("group_mask", keyword))
  565. {
  566. sscanf(valuestr, "%x", &mask);
  567. mMaskGroup = mask;
  568. }
  569. else if (!strcmp("everyone_mask", keyword))
  570. {
  571. sscanf(valuestr, "%x", &mask);
  572. mMaskEveryone = mask;
  573. }
  574. else if (!strcmp("next_owner_mask", keyword))
  575. {
  576. sscanf(valuestr, "%x", &mask);
  577. mMaskNextOwner = mask;
  578. }
  579. else if (!strcmp("creator_id", keyword))
  580. {
  581. sscanf(valuestr, "%255s", uuid_str); /* Flawfinder: ignore */
  582. mCreator.set(uuid_str);
  583. }
  584. else if (!strcmp("owner_id", keyword))
  585. {
  586. sscanf(valuestr, "%255s", uuid_str); /* Flawfinder: ignore */
  587. mOwner.set(uuid_str);
  588. }
  589. else if (!strcmp("last_owner_id", keyword))
  590. {
  591. sscanf(valuestr, "%255s", uuid_str); /* Flawfinder: ignore */
  592. mLastOwner.set(uuid_str);
  593. }
  594. else if (!strcmp("group_id", keyword))
  595. {
  596. sscanf(valuestr, "%255s", uuid_str); /* Flawfinder: ignore */
  597. mGroup.set(uuid_str);
  598. }
  599. else if (!strcmp("group_owned", keyword))
  600. {
  601. sscanf(valuestr, "%d", &mask);
  602. if(mask) mIsGroupOwned = true;
  603. else mIsGroupOwned = false;
  604. }
  605. else
  606. {
  607. llinfos << "unknown keyword " << keyword << " in permissions import" << llendl;
  608. }
  609. }
  610. fix();
  611. return TRUE;
  612. }
  613. BOOL LLPermissions::exportFile(LLFILE* fp) const
  614. {
  615. std::string uuid_str;
  616. fprintf(fp, "\tpermissions 0\n");
  617. fprintf(fp, "\t{\n");
  618. fprintf(fp, "\t\tbase_mask\t%08x\n", mMaskBase);
  619. fprintf(fp, "\t\towner_mask\t%08x\n", mMaskOwner);
  620. fprintf(fp, "\t\tgroup_mask\t%08x\n", mMaskGroup);
  621. fprintf(fp, "\t\teveryone_mask\t%08x\n", mMaskEveryone);
  622. fprintf(fp, "\t\tnext_owner_mask\t%08x\n", mMaskNextOwner);
  623. mCreator.toString(uuid_str);
  624. fprintf(fp, "\t\tcreator_id\t%s\n", uuid_str.c_str());
  625. mOwner.toString(uuid_str);
  626. fprintf(fp, "\t\towner_id\t%s\n", uuid_str.c_str());
  627. mLastOwner.toString(uuid_str);
  628. fprintf(fp, "\t\tlast_owner_id\t%s\n", uuid_str.c_str());
  629. mGroup.toString(uuid_str);
  630. fprintf(fp, "\t\tgroup_id\t%s\n", uuid_str.c_str());
  631. if(mIsGroupOwned)
  632. {
  633. fprintf(fp, "\t\tgroup_owned\t1\n");
  634. }
  635. fprintf(fp,"\t}\n");
  636. return TRUE;
  637. }
  638. BOOL LLPermissions::importLegacyStream(std::istream& input_stream)
  639. {
  640. init(LLUUID::null, LLUUID::null, LLUUID::null, LLUUID::null);
  641. const S32 BUFSIZE = 16384;
  642. // *NOTE: Changing the buffer size will require changing the scanf
  643. // calls below.
  644. char buffer[BUFSIZE]; /* Flawfinder: ignore */
  645. char keyword[256]; /* Flawfinder: ignore */
  646. char valuestr[256]; /* Flawfinder: ignore */
  647. char uuid_str[256]; /* Flawfinder: ignore */
  648. U32 mask;
  649. keyword[0] = '\0';
  650. valuestr[0] = '\0';
  651. while (input_stream.good())
  652. {
  653. input_stream.getline(buffer, BUFSIZE);
  654. sscanf( /* Flawfinder: ignore */
  655. buffer,
  656. " %255s %255s",
  657. keyword, valuestr);
  658. if (!strcmp("{", keyword))
  659. {
  660. continue;
  661. }
  662. if (!strcmp("}",keyword))
  663. {
  664. break;
  665. }
  666. else if (!strcmp("creator_mask", keyword))
  667. {
  668. // legacy support for "creator" masks
  669. sscanf(valuestr, "%x", &mask);
  670. mMaskBase = mask;
  671. fixFairUse();
  672. }
  673. else if (!strcmp("base_mask", keyword))
  674. {
  675. sscanf(valuestr, "%x", &mask);
  676. mMaskBase = mask;
  677. //fixFairUse();
  678. }
  679. else if (!strcmp("owner_mask", keyword))
  680. {
  681. sscanf(valuestr, "%x", &mask);
  682. mMaskOwner = mask;
  683. }
  684. else if (!strcmp("group_mask", keyword))
  685. {
  686. sscanf(valuestr, "%x", &mask);
  687. mMaskGroup = mask;
  688. }
  689. else if (!strcmp("everyone_mask", keyword))
  690. {
  691. sscanf(valuestr, "%x", &mask);
  692. mMaskEveryone = mask;
  693. }
  694. else if (!strcmp("next_owner_mask", keyword))
  695. {
  696. sscanf(valuestr, "%x", &mask);
  697. mMaskNextOwner = mask;
  698. }
  699. else if (!strcmp("creator_id", keyword))
  700. {
  701. sscanf(valuestr, "%255s", uuid_str); /* Flawfinder: ignore */
  702. mCreator.set(uuid_str);
  703. }
  704. else if (!strcmp("owner_id", keyword))
  705. {
  706. sscanf(valuestr, "%255s", uuid_str); /* Flawfinder: ignore */
  707. mOwner.set(uuid_str);
  708. }
  709. else if (!strcmp("last_owner_id", keyword))
  710. {
  711. sscanf(valuestr, "%255s", uuid_str); /* Flawfinder: ignore */
  712. mLastOwner.set(uuid_str);
  713. }
  714. else if (!strcmp("group_id", keyword))
  715. {
  716. sscanf(valuestr, "%255s", uuid_str); /* Flawfinder: ignore */
  717. mGroup.set(uuid_str);
  718. }
  719. else if (!strcmp("group_owned", keyword))
  720. {
  721. sscanf(valuestr, "%d", &mask);
  722. if(mask) mIsGroupOwned = true;
  723. else mIsGroupOwned = false;
  724. }
  725. else
  726. {
  727. llinfos << "unknown keyword " << keyword << " in permissions import" << llendl;
  728. }
  729. }
  730. fix();
  731. return TRUE;
  732. }
  733. BOOL LLPermissions::exportLegacyStream(std::ostream& output_stream) const
  734. {
  735. std::string uuid_str;
  736. output_stream << "\tpermissions 0\n";
  737. output_stream << "\t{\n";
  738. std::string buffer;
  739. buffer = llformat( "\t\tbase_mask\t%08x\n", mMaskBase);
  740. output_stream << buffer;
  741. buffer = llformat( "\t\towner_mask\t%08x\n", mMaskOwner);
  742. output_stream << buffer;
  743. buffer = llformat( "\t\tgroup_mask\t%08x\n", mMaskGroup);
  744. output_stream << buffer;
  745. buffer = llformat( "\t\teveryone_mask\t%08x\n", mMaskEveryone);
  746. output_stream << buffer;
  747. buffer = llformat( "\t\tnext_owner_mask\t%08x\n", mMaskNextOwner);
  748. output_stream << buffer;
  749. mCreator.toString(uuid_str);
  750. output_stream << "\t\tcreator_id\t" << uuid_str << "\n";
  751. mOwner.toString(uuid_str);
  752. output_stream << "\t\towner_id\t" << uuid_str << "\n";
  753. mLastOwner.toString(uuid_str);
  754. output_stream << "\t\tlast_owner_id\t" << uuid_str << "\n";
  755. mGroup.toString(uuid_str);
  756. output_stream << "\t\tgroup_id\t" << uuid_str << "\n";
  757. if(mIsGroupOwned)
  758. {
  759. output_stream << "\t\tgroup_owned\t1\n";
  760. }
  761. output_stream << "\t}\n";
  762. return TRUE;
  763. }
  764. // Deleted LLPermissions::exportFileXML() and LLPermissions::importXML()
  765. // because I can't find any non-test code references to it. 2009-05-04 JC
  766. bool LLPermissions::operator==(const LLPermissions &rhs) const
  767. {
  768. return
  769. (mCreator == rhs.mCreator) &&
  770. (mOwner == rhs.mOwner) &&
  771. (mLastOwner == rhs.mLastOwner ) &&
  772. (mGroup == rhs.mGroup ) &&
  773. (mMaskBase == rhs.mMaskBase ) &&
  774. (mMaskOwner == rhs.mMaskOwner ) &&
  775. (mMaskGroup == rhs.mMaskGroup ) &&
  776. (mMaskEveryone == rhs.mMaskEveryone ) &&
  777. (mMaskNextOwner == rhs.mMaskNextOwner ) &&
  778. (mIsGroupOwned == rhs.mIsGroupOwned);
  779. }
  780. bool LLPermissions::operator!=(const LLPermissions &rhs) const
  781. {
  782. return
  783. (mCreator != rhs.mCreator) ||
  784. (mOwner != rhs.mOwner) ||
  785. (mLastOwner != rhs.mLastOwner ) ||
  786. (mGroup != rhs.mGroup ) ||
  787. (mMaskBase != rhs.mMaskBase ) ||
  788. (mMaskOwner != rhs.mMaskOwner ) ||
  789. (mMaskGroup != rhs.mMaskGroup ) ||
  790. (mMaskEveryone != rhs.mMaskEveryone ) ||
  791. (mMaskNextOwner != rhs.mMaskNextOwner) ||
  792. (mIsGroupOwned != rhs.mIsGroupOwned);
  793. }
  794. std::ostream& operator<<(std::ostream &s, const LLPermissions &perm)
  795. {
  796. s << "{Creator=" << perm.getCreator();
  797. s << ", Owner=" << perm.getOwner();
  798. s << ", Group=" << perm.getGroup();
  799. s << std::hex << ", BaseMask=0x" << perm.getMaskBase();
  800. s << ", OwnerMask=0x" << perm.getMaskOwner();
  801. s << ", EveryoneMask=0x" << perm.getMaskEveryone();
  802. s << ", GroupMask=0x" << perm.getMaskGroup();
  803. s << ", NextOwnerMask=0x" << perm.getMaskNextOwner() << std::dec;
  804. s << "}";
  805. return s;
  806. }
  807. template <>
  808. void LLMetaClassT<LLPermissions>::reflectProperties(LLMetaClass& meta_class)
  809. {
  810. reflectProperty(meta_class, "mCreator", &LLPermissions::mCreator);
  811. reflectProperty(meta_class, "mOwner", &LLPermissions::mOwner);
  812. reflectProperty(meta_class, "mGroup", &LLPermissions::mGroup);
  813. reflectProperty(meta_class, "mIsGroupOwned", &LLPermissions::mIsGroupOwned);
  814. }
  815. // virtual
  816. const LLMetaClass& LLPermissions::getMetaClass() const
  817. {
  818. return LLMetaClassT<LLPermissions>::instance();
  819. }
  820. ///----------------------------------------------------------------------------
  821. /// Class LLAggregatePermissions
  822. ///----------------------------------------------------------------------------
  823. const LLAggregatePermissions LLAggregatePermissions::empty;
  824. LLAggregatePermissions::LLAggregatePermissions()
  825. {
  826. for(S32 i = 0; i < PI_COUNT; ++i)
  827. {
  828. mBits[i] = AP_EMPTY;
  829. }
  830. }
  831. LLAggregatePermissions::EValue LLAggregatePermissions::getValue(PermissionBit bit) const
  832. {
  833. EPermIndex idx = perm2PermIndex(bit);
  834. EValue rv = AP_EMPTY;
  835. if(idx != PI_END)
  836. {
  837. rv = (LLAggregatePermissions::EValue)(mBits[idx]);
  838. }
  839. return rv;
  840. }
  841. // returns the bits compressed into a single byte: 00TTMMCC
  842. // where TT = transfer, MM = modify, and CC = copy
  843. // LSB is to the right
  844. U8 LLAggregatePermissions::getU8() const
  845. {
  846. U8 byte = mBits[PI_TRANSFER];
  847. byte <<= 2;
  848. byte |= mBits[PI_MODIFY];
  849. byte <<= 2;
  850. byte |= mBits[PI_COPY];
  851. return byte;
  852. }
  853. BOOL LLAggregatePermissions::isEmpty() const
  854. {
  855. for(S32 i = 0; i < PI_END; ++i)
  856. {
  857. if(mBits[i] != AP_EMPTY)
  858. {
  859. return FALSE;
  860. }
  861. }
  862. return TRUE;
  863. }
  864. void LLAggregatePermissions::aggregate(PermissionMask mask)
  865. {
  866. BOOL is_allowed = mask & PERM_COPY;
  867. aggregateBit(PI_COPY, is_allowed);
  868. is_allowed = mask & PERM_MODIFY;
  869. aggregateBit(PI_MODIFY, is_allowed);
  870. is_allowed = mask & PERM_TRANSFER;
  871. aggregateBit(PI_TRANSFER, is_allowed);
  872. }
  873. void LLAggregatePermissions::aggregate(const LLAggregatePermissions& ag)
  874. {
  875. for(S32 idx = PI_COPY; idx != PI_END; ++idx)
  876. {
  877. aggregateIndex((EPermIndex)idx, ag.mBits[idx]);
  878. }
  879. }
  880. void LLAggregatePermissions::aggregateBit(EPermIndex idx, BOOL allowed)
  881. {
  882. //if(AP_SOME == mBits[idx]) return; // P4 branch prediction optimization
  883. switch(mBits[idx])
  884. {
  885. case AP_EMPTY:
  886. mBits[idx] = allowed ? AP_ALL : AP_NONE;
  887. break;
  888. case AP_NONE:
  889. mBits[idx] = allowed ? AP_SOME: AP_NONE;
  890. break;
  891. case AP_SOME:
  892. // no-op
  893. break;
  894. case AP_ALL:
  895. mBits[idx] = allowed ? AP_ALL : AP_SOME;
  896. break;
  897. default:
  898. llwarns << "Bad aggregateBit " << (S32)idx << " "
  899. << (allowed ? "true" : "false") << llendl;
  900. break;
  901. }
  902. }
  903. void LLAggregatePermissions::aggregateIndex(EPermIndex idx, U8 bits)
  904. {
  905. switch(mBits[idx])
  906. {
  907. case AP_EMPTY:
  908. mBits[idx] = bits;
  909. break;
  910. case AP_NONE:
  911. switch(bits)
  912. {
  913. case AP_SOME:
  914. case AP_ALL:
  915. mBits[idx] = AP_SOME;
  916. break;
  917. case AP_EMPTY:
  918. case AP_NONE:
  919. default:
  920. // no-op
  921. break;
  922. }
  923. break;
  924. case AP_SOME:
  925. // no-op
  926. break;
  927. case AP_ALL:
  928. switch(bits)
  929. {
  930. case AP_NONE:
  931. case AP_SOME:
  932. mBits[idx] = AP_SOME;
  933. break;
  934. case AP_EMPTY:
  935. case AP_ALL:
  936. default:
  937. // no-op
  938. break;
  939. }
  940. break;
  941. default:
  942. llwarns << "Bad aggregate index " << (S32)idx << " "
  943. << (S32)bits << llendl;
  944. break;
  945. }
  946. }
  947. // static
  948. LLAggregatePermissions::EPermIndex LLAggregatePermissions::perm2PermIndex(PermissionBit bit)
  949. {
  950. EPermIndex idx = PI_END; // past any good value.
  951. switch(bit)
  952. {
  953. case PERM_COPY:
  954. idx = PI_COPY;
  955. break;
  956. case PERM_MODIFY:
  957. idx = PI_MODIFY;
  958. break;
  959. case PERM_TRANSFER:
  960. idx = PI_TRANSFER;
  961. break;
  962. default:
  963. break;
  964. }
  965. return idx;
  966. }
  967. void LLAggregatePermissions::packMessage(LLMessageSystem* msg, const char* field) const
  968. {
  969. msg->addU8Fast(field, getU8());
  970. }
  971. void LLAggregatePermissions::unpackMessage(LLMessageSystem* msg, const char* block, const char* field, S32 block_num)
  972. {
  973. const U8 TWO_BITS = 0x3; // binary 00000011
  974. U8 bits = 0;
  975. msg->getU8Fast(block, field, bits, block_num);
  976. mBits[PI_COPY] = bits & TWO_BITS;
  977. bits >>= 2;
  978. mBits[PI_MODIFY] = bits & TWO_BITS;
  979. bits >>= 2;
  980. mBits[PI_TRANSFER] = bits & TWO_BITS;
  981. }
  982. const std::string AGGREGATE_VALUES[4] =
  983. {
  984. std::string( "Empty" ),
  985. std::string( "None" ),
  986. std::string( "Some" ),
  987. std::string( "All" )
  988. };
  989. std::ostream& operator<<(std::ostream &s, const LLAggregatePermissions &perm)
  990. {
  991. s << "{PI_COPY=" << AGGREGATE_VALUES[perm.mBits[LLAggregatePermissions::PI_COPY]];
  992. s << ", PI_MODIFY=" << AGGREGATE_VALUES[perm.mBits[LLAggregatePermissions::PI_MODIFY]];
  993. s << ", PI_TRANSFER=" << AGGREGATE_VALUES[perm.mBits[LLAggregatePermissions::PI_TRANSFER]];
  994. s << "}";
  995. return s;
  996. }
  997. // This converts a permissions mask into a string for debugging use.
  998. void mask_to_string(U32 mask, char* str)
  999. {
  1000. if (mask & PERM_MOVE)
  1001. {
  1002. *str = 'V';
  1003. }
  1004. else
  1005. {
  1006. *str = ' ';
  1007. }
  1008. str++;
  1009. if (mask & PERM_MODIFY)
  1010. {
  1011. *str = 'M';
  1012. }
  1013. else
  1014. {
  1015. *str = ' ';
  1016. }
  1017. str++;
  1018. if (mask & PERM_COPY)
  1019. {
  1020. *str = 'C';
  1021. }
  1022. else
  1023. {
  1024. *str = ' ';
  1025. }
  1026. str++;
  1027. if (mask & PERM_TRANSFER)
  1028. {
  1029. *str = 'T';
  1030. }
  1031. else
  1032. {
  1033. *str = ' ';
  1034. }
  1035. str++;
  1036. *str = '\0';
  1037. }
  1038. std::string mask_to_string(U32 mask)
  1039. {
  1040. char str[16];
  1041. mask_to_string(mask, str);
  1042. return std::string(str);
  1043. }
  1044. ///----------------------------------------------------------------------------
  1045. /// exported functions
  1046. ///----------------------------------------------------------------------------
  1047. static const std::string PERM_CREATOR_ID_LABEL("creator_id");
  1048. static const std::string PERM_OWNER_ID_LABEL("owner_id");
  1049. static const std::string PERM_LAST_OWNER_ID_LABEL("last_owner_id");
  1050. static const std::string PERM_GROUP_ID_LABEL("group_id");
  1051. static const std::string PERM_IS_OWNER_GROUP_LABEL("is_owner_group");
  1052. static const std::string PERM_BASE_MASK_LABEL("base_mask");
  1053. static const std::string PERM_OWNER_MASK_LABEL("owner_mask");
  1054. static const std::string PERM_GROUP_MASK_LABEL("group_mask");
  1055. static const std::string PERM_EVERYONE_MASK_LABEL("everyone_mask");
  1056. static const std::string PERM_NEXT_OWNER_MASK_LABEL("next_owner_mask");
  1057. LLSD ll_create_sd_from_permissions(const LLPermissions& perm)
  1058. {
  1059. LLSD rv;
  1060. rv[PERM_CREATOR_ID_LABEL] = perm.getCreator();
  1061. rv[PERM_OWNER_ID_LABEL] = perm.getOwner();
  1062. rv[PERM_LAST_OWNER_ID_LABEL] = perm.getLastOwner();
  1063. rv[PERM_GROUP_ID_LABEL] = perm.getGroup();
  1064. rv[PERM_IS_OWNER_GROUP_LABEL] = perm.isGroupOwned();
  1065. rv[PERM_BASE_MASK_LABEL] = (S32)perm.getMaskBase();
  1066. rv[PERM_OWNER_MASK_LABEL] = (S32)perm.getMaskOwner();
  1067. rv[PERM_GROUP_MASK_LABEL] = (S32)perm.getMaskGroup();
  1068. rv[PERM_EVERYONE_MASK_LABEL] = (S32)perm.getMaskEveryone();
  1069. rv[PERM_NEXT_OWNER_MASK_LABEL] = (S32)perm.getMaskNextOwner();
  1070. return rv;
  1071. }
  1072. LLPermissions ll_permissions_from_sd(const LLSD& sd_perm)
  1073. {
  1074. LLPermissions rv;
  1075. rv.init(
  1076. sd_perm[PERM_CREATOR_ID_LABEL].asUUID(),
  1077. sd_perm[PERM_OWNER_ID_LABEL].asUUID(),
  1078. sd_perm[PERM_LAST_OWNER_ID_LABEL].asUUID(),
  1079. sd_perm[PERM_GROUP_ID_LABEL].asUUID());
  1080. // We do a cast to U32 here since LLSD does not attempt to
  1081. // represent unsigned ints.
  1082. PermissionMask mask;
  1083. mask = (U32)(sd_perm[PERM_BASE_MASK_LABEL].asInteger());
  1084. rv.setMaskBase(mask);
  1085. mask = (U32)(sd_perm[PERM_OWNER_MASK_LABEL].asInteger());
  1086. rv.setMaskOwner(mask);
  1087. mask = (U32)(sd_perm[PERM_EVERYONE_MASK_LABEL].asInteger());
  1088. rv.setMaskEveryone(mask);
  1089. mask = (U32)(sd_perm[PERM_GROUP_MASK_LABEL].asInteger());
  1090. rv.setMaskGroup(mask);
  1091. mask = (U32)(sd_perm[PERM_NEXT_OWNER_MASK_LABEL].asInteger());
  1092. rv.setMaskNext(mask);
  1093. rv.fix();
  1094. return rv;
  1095. }