| | 114 | |
| | 115 | bool CAdbkACL::SamePrincipal(const CAdbkACL& acl) const |
| | 116 | { |
| | 117 | if (mType != acl.mType) |
| | 118 | return false; |
| | 119 | |
| | 120 | switch(mType) |
| | 121 | { |
| | 122 | case ePrincipal_unknown: |
| | 123 | default: |
| | 124 | return false; |
| | 125 | case ePrincipal_href: |
| | 126 | return mUID == acl.mUID; |
| | 127 | case ePrincipal_all: |
| | 128 | case ePrincipal_authenticated: |
| | 129 | case ePrincipal_unauthenticated: |
| | 130 | case ePrincipal_self: |
| | 131 | return true; |
| | 132 | case ePrincipal_property: |
| | 133 | return mPropName == acl.mPropName; |
| | 134 | } |
| | 135 | } |
| | 136 | |
| | 137 | bool CAdbkACL::AllRights() const |
| | 138 | { |
| | 139 | return HasRight(eAdbkACL_All) && |
| | 140 | HasRight(eAdbkACL_Lookup) && |
| | 141 | HasRight(eAdbkACL_Read) && |
| | 142 | HasRight(eAdbkACL_Write) && |
| | 143 | HasRight(eAdbkACL_Create) && |
| | 144 | HasRight(eAdbkACL_Delete) && |
| | 145 | HasRight(eAdbkACL_Admin); |
| | 146 | } |
| | 147 | |
| | 148 | bool CAdbkACL::ParseACE(const xmllib::XMLNode* acenode) |
| | 149 | { |
| | 150 | // Get the principal |
| | 151 | const xmllib::XMLNode* principal = acenode->GetChild(http::webdav::cProperty_principal); |
| | 152 | if (principal == NULL) |
| | 153 | return false; |
| | 154 | |
| | 155 | // Determine principal info |
| | 156 | const xmllib::XMLNode* child = NULL; |
| | 157 | if ((child = principal->GetChild(http::webdav::cProperty_href)) != NULL) |
| | 158 | { |
| | 159 | cdstring href(child->Data()); |
| | 160 | href.DecodeURL(); |
| | 161 | SetPrincipalType(CAdbkACL::ePrincipal_href, href); |
| | 162 | } |
| | 163 | else if ((child = principal->GetChild(http::webdav::cProperty_all)) != NULL) |
| | 164 | { |
| | 165 | SetPrincipalType(CAdbkACL::ePrincipal_all); |
| | 166 | } |
| | 167 | else if ((child = principal->GetChild(http::webdav::cProperty_authenticated)) != NULL) |
| | 168 | { |
| | 169 | SetPrincipalType(CAdbkACL::ePrincipal_authenticated); |
| | 170 | } |
| | 171 | else if ((child = principal->GetChild(http::webdav::cProperty_unauthenticated)) != NULL) |
| | 172 | { |
| | 173 | SetPrincipalType(CAdbkACL::ePrincipal_unauthenticated); |
| | 174 | } |
| | 175 | else if ((child = principal->GetChild(http::webdav::cProperty_property)) != NULL) |
| | 176 | { |
| | 177 | if (child->Children().size() == 1) |
| | 178 | { |
| | 179 | xmllib::XMLName propname(*child->Children().front()); |
| | 180 | SetPrincipalType(CAdbkACL::ePrincipal_property, propname); |
| | 181 | } |
| | 182 | else |
| | 183 | SetPrincipalType(CAdbkACL::ePrincipal_property); |
| | 184 | } |
| | 185 | else if ((child = principal->GetChild(http::webdav::cProperty_self)) != NULL) |
| | 186 | { |
| | 187 | SetPrincipalType(CAdbkACL::ePrincipal_self); |
| | 188 | } |
| | 189 | |
| | 190 | // Determine rights |
| | 191 | child = acenode->GetChild(http::webdav::cProperty_grant); |
| | 192 | if (child == NULL) |
| | 193 | child = acenode->GetChild(http::webdav::cProperty_deny); |
| | 194 | if (child != NULL) |
| | 195 | { |
| | 196 | ParsePrivilege(child, child->CompareFullName(http::webdav::cProperty_grant)); |
| | 197 | } |
| | 198 | |
| | 199 | // Determine protected/inherited state |
| | 200 | if ((acenode->GetChild(http::webdav::cProperty_protected) != NULL) || |
| | 201 | (acenode->GetChild(http::webdav::cProperty_inherited) != NULL)) |
| | 202 | SetCanChange(false); |
| | 203 | |
| | 204 | // Determine inheritable/non-inheritable |
| | 205 | if (acenode->GetChild(http::slide::cInheritable_comp) != NULL) |
| | 206 | SetInheritable(true); |
| | 207 | else if (acenode->GetChild(http::slide::cNonInheritable_comp) != NULL) |
| | 208 | SetInheritable(false); |
| | 209 | |
| | 210 | return true; |
| | 211 | } |
| | 212 | |
| | 213 | void CAdbkACL::ParsePrivilege(const xmllib::XMLNode* parent, bool add) |
| | 214 | { |
| | 215 | // parent node contains one of more privilege nodes which we parse |
| | 216 | for(xmllib::XMLNodeList::const_iterator iter1 = parent->Children().begin(); iter1 != parent->Children().end(); iter1++) |
| | 217 | { |
| | 218 | xmllib::XMLNode* privilege = *iter1; |
| | 219 | |
| | 220 | // Look for privilege |
| | 221 | if (!privilege->CompareFullName(http::webdav::cProperty_privilege)) |
| | 222 | continue; |
| | 223 | |
| | 224 | // Now get rights within the privilege |
| | 225 | for(xmllib::XMLNodeList::const_iterator iter2 = privilege->Children().begin(); iter2 != privilege->Children().end(); iter2++) |
| | 226 | { |
| | 227 | xmllib::XMLNode* right = *iter2; |
| | 228 | cdstring name = right->Name(); |
| | 229 | MapRight(name, add); |
| | 230 | } |
| | 231 | } |
| | 232 | } |
| | 233 | |
| | 234 | void CAdbkACL::MapRight(const cdstring& right, bool add) |
| | 235 | { |
| | 236 | // Cache the mappings for this type of client |
| | 237 | typedef map<cdstring, unsigned long> CMapRights; |
| | 238 | static CMapRights sMapRights; |
| | 239 | |
| | 240 | if (sMapRights.empty()) |
| | 241 | { |
| | 242 | sMapRights.insert(CMapRights::value_type(http::webdav::cProperty_privilege_read.Name(), eAdbkACL_Lookup | eAdbkACL_Read)); |
| | 243 | sMapRights.insert(CMapRights::value_type(http::webdav::cProperty_privilege_write.Name(), eAdbkACL_Write)); |
| | 244 | sMapRights.insert(CMapRights::value_type(http::webdav::cProperty_privilege_write_properties.Name(), 0)); |
| | 245 | sMapRights.insert(CMapRights::value_type(http::webdav::cProperty_privilege_write_content.Name(), eAdbkACL_Write)); |
| | 246 | sMapRights.insert(CMapRights::value_type(http::webdav::cProperty_privilege_unlock.Name(), 0)); |
| | 247 | sMapRights.insert(CMapRights::value_type(http::webdav::cProperty_privilege_read_acl.Name(), 0)); |
| | 248 | sMapRights.insert(CMapRights::value_type(http::webdav::cProperty_privilege_read_current_user_privilege_set.Name(), 0)); |
| | 249 | sMapRights.insert(CMapRights::value_type(http::webdav::cProperty_privilege_write_acl.Name(), eAdbkACL_Admin)); |
| | 250 | sMapRights.insert(CMapRights::value_type(http::webdav::cProperty_privilege_bind.Name(), eAdbkACL_Create)); |
| | 251 | sMapRights.insert(CMapRights::value_type(http::webdav::cProperty_privilege_unbind.Name(), eAdbkACL_Delete)); |
| | 252 | sMapRights.insert(CMapRights::value_type(http::webdav::cProperty_privilege_all.Name(), eAdbkACL_Lookup | |
| | 253 | eAdbkACL_Read | |
| | 254 | eAdbkACL_Write | |
| | 255 | eAdbkACL_Create | |
| | 256 | eAdbkACL_Delete | |
| | 257 | eAdbkACL_Admin | |
| | 258 | eAdbkACL_All)); |
| | 259 | } |
| | 260 | |
| | 261 | // Find entry in map |
| | 262 | CMapRights::const_iterator found = sMapRights.find(right); |
| | 263 | if (found != sMapRights.end()) |
| | 264 | { |
| | 265 | SetRight((*found).second, add); |
| | 266 | } |
| | 267 | } |
| | 268 | |
| | 269 | void CAdbkACL::GenerateACE(xmllib::XMLDocument* xmldoc, xmllib::XMLNode* aclnode, bool can_use_inheritable) const |
| | 270 | { |
| | 271 | // Structure of ace is: |
| | 272 | // |
| | 273 | // <DAV:ace> |
| | 274 | // <S:inheritable xmlns:S="http://jakarta.apache.org/slide/"> / <S:non-inheritable xmlns:S="http://jakarta.apache.org/slide/"> |
| | 275 | // <DAV:principal>...</DAV:principal> |
| | 276 | // <DAV:grant>...</DAV:grant> |
| | 277 | // </DAV:ace> |
| | 278 | |
| | 279 | // <DAV:ace> element |
| | 280 | xmllib::XMLNode* ace = new xmllib::XMLNode(xmldoc, aclnode, http::webdav::cProperty_ace); |
| | 281 | |
| | 282 | // Handle inheritable specialisation |
| | 283 | if (can_use_inheritable) |
| | 284 | { |
| | 285 | if (IsInheritable()) |
| | 286 | new xmllib::XMLNode(xmldoc, ace, http::slide::cInheritable_comp); |
| | 287 | else |
| | 288 | new xmllib::XMLNode(xmldoc, ace, http::slide::cNonInheritable_comp); |
| | 289 | } |
| | 290 | |
| | 291 | // <DAV:principal> element |
| | 292 | xmllib::XMLNode* principal = new xmllib::XMLNode(xmldoc, ace, http::webdav::cProperty_principal); |
| | 293 | |
| | 294 | // Principal type |
| | 295 | switch(GetPrincipalType()) |
| | 296 | { |
| | 297 | case CAdbkACL::ePrincipal_href: |
| | 298 | default: |
| | 299 | { |
| | 300 | // <DAV:href> element |
| | 301 | xmllib::XMLNode* href = new xmllib::XMLNode(xmldoc, principal, http::webdav::cProperty_href); |
| | 302 | cdstring txt(GetUID()); |
| | 303 | if (txt.find('%') == cdstring::npos) |
| | 304 | txt.EncodeURL('/'); |
| | 305 | href->SetData(txt); |
| | 306 | break; |
| | 307 | } |
| | 308 | case CAdbkACL::ePrincipal_all: |
| | 309 | { |
| | 310 | // <DAV:all> element |
| | 311 | new xmllib::XMLNode(xmldoc, principal, http::webdav::cProperty_all); |
| | 312 | break; |
| | 313 | } |
| | 314 | case CAdbkACL::ePrincipal_authenticated: |
| | 315 | { |
| | 316 | // <DAV:authenticated> element |
| | 317 | new xmllib::XMLNode(xmldoc, principal, http::webdav::cProperty_authenticated); |
| | 318 | break; |
| | 319 | } |
| | 320 | case CAdbkACL::ePrincipal_unauthenticated: |
| | 321 | { |
| | 322 | // <DAV:unauthenticated> element |
| | 323 | new xmllib::XMLNode(xmldoc, principal, http::webdav::cProperty_unauthenticated); |
| | 324 | break; |
| | 325 | } |
| | 326 | case CAdbkACL::ePrincipal_property: |
| | 327 | { |
| | 328 | // <DAV:property> element - the UID is the property element name |
| | 329 | xmllib::XMLNode* property = new xmllib::XMLNode(xmldoc, principal, http::webdav::cProperty_property); |
| | 330 | xmllib::XMLNode* propname = new xmllib::XMLNode(xmldoc, property, GetPropName()); |
| | 331 | break; |
| | 332 | } |
| | 333 | case CAdbkACL::ePrincipal_self: |
| | 334 | { |
| | 335 | // <DAV:self> element |
| | 336 | new xmllib::XMLNode(xmldoc, principal, http::webdav::cProperty_self); |
| | 337 | break; |
| | 338 | } |
| | 339 | } |
| | 340 | |
| | 341 | // Do grant rights for each one set |
| | 342 | |
| | 343 | // <DAV:grant> element |
| | 344 | xmllib::XMLNode* grant = new xmllib::XMLNode(xmldoc, ace, http::webdav::cProperty_grant); |
| | 345 | |
| | 346 | // Special check for "DAV:all" |
| | 347 | if (AllRights() || |
| | 348 | HasRight(CAdbkACL::eAdbkACL_Lookup) && |
| | 349 | HasRight(CAdbkACL::eAdbkACL_Read) && |
| | 350 | HasRight(CAdbkACL::eAdbkACL_Write) && |
| | 351 | HasRight(CAdbkACL::eAdbkACL_Create) && |
| | 352 | HasRight(CAdbkACL::eAdbkACL_Delete) && |
| | 353 | HasRight(CAdbkACL::eAdbkACL_Admin)) |
| | 354 | new xmllib::XMLNode(xmldoc, new xmllib::XMLNode(xmldoc, grant, http::webdav::cProperty_privilege), http::webdav::cProperty_privilege_all); |
| | 355 | else |
| | 356 | { |
| | 357 | if (HasRight(CAdbkACL::eAdbkACL_Lookup) || HasRight(CAdbkACL::eAdbkACL_Read)) |
| | 358 | new xmllib::XMLNode(xmldoc, new xmllib::XMLNode(xmldoc, grant, http::webdav::cProperty_privilege), http::webdav::cProperty_privilege_read); |
| | 359 | if (HasRight(CAdbkACL::eAdbkACL_Write)) |
| | 360 | new xmllib::XMLNode(xmldoc, new xmllib::XMLNode(xmldoc, grant, http::webdav::cProperty_privilege), http::webdav::cProperty_privilege_write); |
| | 361 | if (HasRight(CAdbkACL::eAdbkACL_Create)) |
| | 362 | new xmllib::XMLNode(xmldoc, new xmllib::XMLNode(xmldoc, grant, http::webdav::cProperty_privilege), http::webdav::cProperty_privilege_bind); |
| | 363 | if (HasRight(CAdbkACL::eAdbkACL_Delete)) |
| | 364 | new xmllib::XMLNode(xmldoc, new xmllib::XMLNode(xmldoc, grant, http::webdav::cProperty_privilege), http::webdav::cProperty_privilege_unbind); |
| | 365 | if (HasRight(CAdbkACL::eAdbkACL_Admin)) |
| | 366 | { |
| | 367 | new xmllib::XMLNode(xmldoc, new xmllib::XMLNode(xmldoc, grant, http::webdav::cProperty_privilege), http::webdav::cProperty_privilege_read_acl); |
| | 368 | new xmllib::XMLNode(xmldoc, new xmllib::XMLNode(xmldoc, grant, http::webdav::cProperty_privilege), http::webdav::cProperty_privilege_write_acl); |
| | 369 | } |
| | 370 | } |
| | 371 | } |