1: <?php
2: 3: 4: 5: 6: 7: 8: 9: 10:
11: dbg_error_log("ACL", "method handler");
12:
13: require_once('DAVResource.php');
14:
15: $request->NeedPrivilege('DAV::write-acl');
16:
17: if ( ! ini_get('open_basedir') && (isset($c->dbg['ALL']) || (isset($c->dbg['put']) && $c->dbg['put'])) ) {
18: $fh = fopen('/var/log/davical/MOVE.debug','w');
19: if ( $fh ) {
20: fwrite($fh,$request->raw_post);
21: fclose($fh);
22: }
23: }
24:
25: $resource = new DAVResource( $request->path );
26:
27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85: 86: 87: 88: 89:
90:
91: $position = 0;
92: $xmltree = BuildXMLTree( $request->xml_tags, $position);
93: $aces = $xmltree->GetPath("/DAV::acl/*");
94:
95: $grantor = new DAVResource($request->path);
96: if ( ! $grantor->Exists() ) $request->DoResponse( 404 );
97: if ( ! $grantor->IsCollection() )
98: $request->PreconditionFailed(403,'not-supported-privilege','ACLs are only supported on Principals or Collections');
99:
100: $grantor->NeedPrivilege('write-acl');
101:
102: $cache_delete_list = array();
103:
104: $qry = new AwlQuery('BEGIN');
105: $qry->Exec('ACL',__LINE__,__FILE__);
106:
107: function process_ace( $grantor, $by_principal, $by_collection, $ace ) {
108: global $cache_delete_list, $request;
109:
110: $elements = $ace->GetContent();
111: $principal_node = $elements[0];
112: $grant = $elements[1];
113: if ( $principal_node->GetNSTag() != 'DAV::principal' ) $request->MalformedRequest('ACL request must contain a principal, not '.$principal->GetNSTag());
114: $grant_tag = $grant->GetNSTag();
115: if ( $grant_tag == 'DAV::deny' ) $request->PreconditionFailed(403,'grant-only');
116: if ( $grant_tag == 'DAV::invert' ) $request->PreconditionFailed(403,'no-invert');
117: if ( $grant->GetNSTag() != 'DAV::grant' ) $request->MalformedRequest('ACL request must contain a principal for each ACE');
118:
119: $privilege_names = array();
120: $xml_privs = $grant->GetPath("/DAV::grant/DAV::privilege/*");
121: foreach( $xml_privs AS $k => $priv ) {
122: $privilege_names[] = $priv->GetNSTag();
123: }
124: $privileges = privilege_to_bits($privilege_names);
125:
126: $principal_content = $principal_node->GetContent();
127: if ( count($principal_content) != 1 ) $request->MalformedRequest('ACL request must contain exactly one principal per ACE');
128: $principal_content = $principal_content[0];
129: switch( $principal_content->GetNSTag() ) {
130: case 'DAV::property':
131: $principal_property = $principal_content->GetContent();
132: if ( $principal_property[0]->GetNSTag() != 'DAV::owner' ) $request->PreconditionFailed(403, 'recognized-principal' );
133: if ( privilege_to_bits('all') != $privileges ) {
134: $request->PreconditionFailed(403, 'no-protected-ace-conflict', 'Owner must always have all permissions' );
135: }
136: continue;
137: break;
138:
139: case 'DAV::unauthenticated':
140: $request->PreconditionFailed(403, 'allowed-principal', 'May not set privileges for unauthenticated users' );
141: break;
142:
143: case 'DAV::href':
144: $principal_type = 'href';
145: $grantee = new DAVResource( DeconstructURL($principal_content->GetContent()) );
146: $grantee_id = $grantee->getProperty('principal_id');
147: if ( !$grantee->Exists() || !$grantee->IsPrincipal() )
148: $request->PreconditionFailed(403,'recognized-principal', 'Principal "' + $principal_content->GetContent() + '" not found.');
149: $sqlparms = array( ':to_principal' => $grantee_id);
150: $where = 'WHERE to_principal=:to_principal AND ';
151: if ( isset($by_principal) ) {
152: $sqlparms[':by_principal'] = $by_principal;
153: $where .= 'by_principal = :by_principal';
154: }
155: else {
156: $sqlparms[':by_collection'] = $by_collection;
157: $where .= 'by_collection = :by_collection';
158: }
159: $qry = new AwlQuery('SELECT privileges FROM grants '.$where, $sqlparms);
160: if ( $qry->Exec('ACL',__LINE__,__FILE__) && $qry->rows() == 1 && $current = $qry->Fetch() ) {
161: $sql = 'UPDATE grants SET privileges=:privileges::INT::BIT(24) '.$where;
162: }
163: else {
164: $sqlparms[':by_principal'] = $by_principal;
165: $sqlparms[':by_collection'] = $by_collection;
166: $sql = 'INSERT INTO grants (by_principal, by_collection, to_principal, privileges) VALUES(:by_principal, :by_collection, :to_principal, :privileges::INT::BIT(24))';
167: }
168: $sqlparms[':privileges'] = $privileges;
169: $qry = new AwlQuery($sql, $sqlparms);
170: if ( $qry->Exec('ACL',__LINE__,__FILE__) ) {
171: Principal::cacheDelete('dav_name',$grantee->dav_name());
172: Principal::cacheFlush('principal_id IN (SELECT member_id FROM group_member WHERE group_id = ?)', array($grantee_id));
173: }
174: break;
175:
176: case 'DAV::authenticated':
177: $principal_type = 'authenticated';
178: if ( bindec($grantor->GetProperty('default_privileges')) == $privileges ) continue;
179: $sqlparms = array( ':privileges' => $privileges );
180: if ( isset($by_collection) ) {
181: $sql = 'UPDATE collection SET default_privileges=:privileges::INT::BIT(24) WHERE collection_id=:by_collection';
182: $sqlparms[':by_collection'] = $by_collection;
183: }
184: else {
185: $sql = 'UPDATE principal SET default_privileges=:privileges::INT::BIT(24) WHERE principal_id=:by_principal';
186: $sqlparms[':by_principal'] = $by_principal;
187: }
188: $qry = new AwlQuery($sql, $sqlparms);
189: if ( $qry->Exec('ACL',__LINE__,__FILE__) ) {
190: 191: 192:
193: Principal::cacheFlush('TRUE');
194: }
195: break;
196:
197: case 'DAV::all':
198:
199: $request->PreconditionFailed(403, 'allowed-principal', 'May not set privileges for unauthenticated users' );
200: break;
201:
202: default:
203: $request->PreconditionFailed(403, 'recognized-principal' );
204: break;
205: }
206:
207: }
208:
209: $by_principal = ($grantor->IsPrincipal() ? $grantor->GetProperty('principal_id') : null);
210: $by_collection = ($grantor->IsPrincipal() ? null : $grantor->GetProperty('collection_id'));
211:
212: foreach( $aces AS $k => $ace ) {
213: process_ace($grantor, $by_principal, $by_collection, $ace);
214: }
215:
216: $qry = new AwlQuery('COMMIT');
217: $qry->Exec('ACL',__LINE__,__FILE__);
218:
219:
220: $request->DoResponse( 200 );
221: