blob: 27e32ed0e5287c9456e2a850b68d2793132c9957 [file] [log] [blame]
cristy3ed852e2009-09-05 21:47:34 +00001/*
2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3% %
4% %
5% PPPP OOO L IIIII CCCC Y Y %
6% P P O O L I C Y Y %
7% PPPP O O L I C Y %
8% P O O L I C Y %
9% P OOO LLLLL IIIII CCCC Y %
10% %
11% %
12% MagickCore Policy Methods %
13% %
14% Software Design %
15% John Cristy %
16% July 1992 %
17% %
18% %
cristy7e41fe82010-12-04 23:12:08 +000019% Copyright 1999-2011 ImageMagick Studio LLC, a non-profit organization %
cristy3ed852e2009-09-05 21:47:34 +000020% dedicated to making software imaging solutions freely available. %
21% %
22% You may not use this file except in compliance with the License. You may %
23% obtain a copy of the License at %
24% %
25% http://www.imagemagick.org/script/license.php %
26% %
27% Unless required by applicable law or agreed to in writing, software %
28% distributed under the License is distributed on an "AS IS" BASIS, %
29% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %
30% See the License for the specific language governing permissions and %
31% limitations under the License. %
32% %
33%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
34%
35% We use linked-lists because splay-trees do not currently support duplicate
36% key / value pairs (.e.g X11 green compliance and SVG green compliance).
37%
38*/
39
40/*
41 Include declarations.
42*/
cristy4c08aed2011-07-01 19:47:50 +000043#include "MagickCore/studio.h"
44#include "MagickCore/client.h"
45#include "MagickCore/configure.h"
46#include "MagickCore/exception.h"
47#include "MagickCore/exception-private.h"
48#include "MagickCore/memory_.h"
49#include "MagickCore/monitor.h"
50#include "MagickCore/monitor-private.h"
51#include "MagickCore/option.h"
52#include "MagickCore/policy.h"
cristy5ff4eaf2011-09-03 01:38:02 +000053#include "MagickCore/policy-private.h"
cristy4c08aed2011-07-01 19:47:50 +000054#include "MagickCore/semaphore.h"
55#include "MagickCore/string_.h"
56#include "MagickCore/token.h"
57#include "MagickCore/utility.h"
58#include "MagickCore/xml-tree.h"
cristy3ed852e2009-09-05 21:47:34 +000059
60/*
61 Define declarations.
62*/
63#define PolicyFilename "policy.xml"
64
65/*
cristy54a531d2009-10-21 17:58:01 +000066 Typedef declarations.
cristy3ed852e2009-09-05 21:47:34 +000067*/
68struct _PolicyInfo
69{
70 char
cristy54a531d2009-10-21 17:58:01 +000071 *path;
cristy3ed852e2009-09-05 21:47:34 +000072
73 PolicyDomain
74 domain;
75
76 PolicyRights
77 rights;
78
79 char
cristy54a531d2009-10-21 17:58:01 +000080 *name,
cristy3ed852e2009-09-05 21:47:34 +000081 *pattern,
82 *value;
83
84 MagickBooleanType
cristy54a531d2009-10-21 17:58:01 +000085 exempt,
cristy3ed852e2009-09-05 21:47:34 +000086 stealth,
87 debug;
88
89 SemaphoreInfo
90 *semaphore;
91
cristybb503372010-05-27 20:51:26 +000092 size_t
cristy3ed852e2009-09-05 21:47:34 +000093 signature;
94};
cristy54a531d2009-10-21 17:58:01 +000095
96typedef struct _PolicyMapInfo
97{
98 const PolicyDomain
99 domain;
100
101 const PolicyRights
102 rights;
103
104 const char
105 *name,
106 *pattern,
107 *value;
108} PolicyMapInfo;
cristy3ed852e2009-09-05 21:47:34 +0000109
110/*
111 Static declarations.
112*/
cristy54a531d2009-10-21 17:58:01 +0000113static const PolicyMapInfo
114 PolicyMap[] =
115 {
cristyfa378d92009-10-23 15:41:15 +0000116 { UndefinedPolicyDomain, UndefinedPolicyRights, (const char *) NULL,
117 (const char *) NULL, (const char *) NULL }
cristy54a531d2009-10-21 17:58:01 +0000118 };
119
cristy3ed852e2009-09-05 21:47:34 +0000120static LinkedListInfo
121 *policy_list = (LinkedListInfo *) NULL;
122
123static SemaphoreInfo
124 *policy_semaphore = (SemaphoreInfo *) NULL;
125
126static volatile MagickBooleanType
127 instantiate_policy = MagickFalse;
128
129/*
130 Forward declarations.
131*/
132static MagickBooleanType
133 InitializePolicyList(ExceptionInfo *),
134 LoadPolicyLists(const char *,ExceptionInfo *);
135
136/*
137%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
138% %
139% %
140% %
cristy3ed852e2009-09-05 21:47:34 +0000141+ G e t P o l i c y I n f o %
142% %
143% %
144% %
145%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
146%
147% GetPolicyInfo() searches the policy list for the specified name and if found
148% returns attributes for that policy.
149%
150% The format of the GetPolicyInfo method is:
151%
152% PolicyInfo *GetPolicyInfo(const char *name,ExceptionInfo *exception)
153%
154% A description of each parameter follows:
155%
156% o name: the policy name.
157%
158% o exception: return any errors or warnings in this structure.
159%
160*/
161static PolicyInfo *GetPolicyInfo(const char *name,ExceptionInfo *exception)
162{
163 char
164 policyname[MaxTextExtent];
165
166 register PolicyInfo
167 *p;
168
169 register char
170 *q;
171
172 assert(exception != (ExceptionInfo *) NULL);
173 if ((policy_list == (LinkedListInfo *) NULL) ||
174 (instantiate_policy == MagickFalse))
175 if (InitializePolicyList(exception) == MagickFalse)
176 return((PolicyInfo *) NULL);
177 if ((policy_list == (LinkedListInfo *) NULL) ||
178 (IsLinkedListEmpty(policy_list) != MagickFalse))
179 return((PolicyInfo *) NULL);
180 if ((name == (const char *) NULL) || (LocaleCompare(name,"*") == 0))
181 return((PolicyInfo *) GetValueFromLinkedList(policy_list,0));
182 /*
183 Strip names of whitespace.
184 */
185 (void) CopyMagickString(policyname,name,MaxTextExtent);
186 for (q=policyname; *q != '\0'; q++)
187 {
188 if (isspace((int) ((unsigned char) *q)) == 0)
189 continue;
190 (void) CopyMagickString(q,q+1,MaxTextExtent);
191 q--;
192 }
193 /*
194 Search for policy tag.
195 */
cristyf84a1932010-01-03 18:00:18 +0000196 LockSemaphoreInfo(policy_semaphore);
cristy3ed852e2009-09-05 21:47:34 +0000197 ResetLinkedListIterator(policy_list);
198 p=(PolicyInfo *) GetNextValueInLinkedList(policy_list);
199 while (p != (PolicyInfo *) NULL)
200 {
201 if (LocaleCompare(policyname,p->name) == 0)
202 break;
203 p=(PolicyInfo *) GetNextValueInLinkedList(policy_list);
204 }
cristy6446d622009-11-02 01:17:45 +0000205 if (p != (PolicyInfo *) NULL)
cristy3ed852e2009-09-05 21:47:34 +0000206 (void) InsertValueInLinkedList(policy_list,0,
207 RemoveElementByValueFromLinkedList(policy_list,p));
cristyf84a1932010-01-03 18:00:18 +0000208 UnlockSemaphoreInfo(policy_semaphore);
cristy3ed852e2009-09-05 21:47:34 +0000209 return(p);
210}
211
212/*
213%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
214% %
215% %
216% %
217% G e t P o l i c y I n f o L i s t %
218% %
219% %
220% %
221%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
222%
223% GetPolicyInfoList() returns any policies that match the specified pattern.
224%
225% The format of the GetPolicyInfoList function is:
226%
227% const PolicyInfo **GetPolicyInfoList(const char *pattern,
cristybb503372010-05-27 20:51:26 +0000228% size_t *number_policies,ExceptionInfo *exception)
cristy3ed852e2009-09-05 21:47:34 +0000229%
230% A description of each parameter follows:
231%
232% o pattern: Specifies a pointer to a text string containing a pattern.
233%
234% o number_policies: returns the number of policies in the list.
235%
236% o exception: return any errors or warnings in this structure.
237%
238*/
239MagickExport const PolicyInfo **GetPolicyInfoList(const char *pattern,
cristybb503372010-05-27 20:51:26 +0000240 size_t *number_policies,ExceptionInfo *exception)
cristy3ed852e2009-09-05 21:47:34 +0000241{
242 const PolicyInfo
243 **policies;
244
245 register const PolicyInfo
246 *p;
247
cristybb503372010-05-27 20:51:26 +0000248 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +0000249 i;
250
251 /*
252 Allocate policy list.
253 */
254 assert(pattern != (char *) NULL);
255 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",pattern);
cristybb503372010-05-27 20:51:26 +0000256 assert(number_policies != (size_t *) NULL);
cristy3ed852e2009-09-05 21:47:34 +0000257 *number_policies=0;
258 p=GetPolicyInfo("*",exception);
259 if (p == (const PolicyInfo *) NULL)
260 return((const PolicyInfo **) NULL);
261 policies=(const PolicyInfo **) AcquireQuantumMemory((size_t)
262 GetNumberOfElementsInLinkedList(policy_list)+1UL,sizeof(*policies));
263 if (policies == (const PolicyInfo **) NULL)
264 return((const PolicyInfo **) NULL);
265 /*
266 Generate policy list.
267 */
cristyf84a1932010-01-03 18:00:18 +0000268 LockSemaphoreInfo(policy_semaphore);
cristy3ed852e2009-09-05 21:47:34 +0000269 ResetLinkedListIterator(policy_list);
270 p=(const PolicyInfo *) GetNextValueInLinkedList(policy_list);
271 for (i=0; p != (const PolicyInfo *) NULL; )
272 {
273 if ((p->stealth == MagickFalse) &&
274 (GlobExpression(p->name,pattern,MagickFalse) != MagickFalse))
275 policies[i++]=p;
276 p=(const PolicyInfo *) GetNextValueInLinkedList(policy_list);
277 }
cristyf84a1932010-01-03 18:00:18 +0000278 UnlockSemaphoreInfo(policy_semaphore);
cristy3ed852e2009-09-05 21:47:34 +0000279 policies[i]=(PolicyInfo *) NULL;
cristybb503372010-05-27 20:51:26 +0000280 *number_policies=(size_t) i;
cristy3ed852e2009-09-05 21:47:34 +0000281 return(policies);
282}
283
284/*
285%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
286% %
287% %
288% %
289% G e t P o l i c y L i s t %
290% %
291% %
292% %
293%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
294%
295% GetPolicyList() returns any policies that match the specified pattern.
296%
297% The format of the GetPolicyList function is:
298%
cristybb503372010-05-27 20:51:26 +0000299% char **GetPolicyList(const char *pattern,size_t *number_policies,
cristy3ed852e2009-09-05 21:47:34 +0000300% ExceptionInfo *exception)
301%
302% A description of each parameter follows:
303%
304% o pattern: a pointer to a text string containing a pattern.
305%
306% o number_policies: returns the number of policies in the list.
307%
308% o exception: return any errors or warnings in this structure.
309%
310*/
311MagickExport char **GetPolicyList(const char *pattern,
cristybb503372010-05-27 20:51:26 +0000312 size_t *number_policies,ExceptionInfo *exception)
cristy3ed852e2009-09-05 21:47:34 +0000313{
314 char
315 **policies;
316
317 register const PolicyInfo
318 *p;
319
cristybb503372010-05-27 20:51:26 +0000320 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +0000321 i;
322
323 /*
324 Allocate policy list.
325 */
326 assert(pattern != (char *) NULL);
327 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",pattern);
cristybb503372010-05-27 20:51:26 +0000328 assert(number_policies != (size_t *) NULL);
cristy3ed852e2009-09-05 21:47:34 +0000329 *number_policies=0;
330 p=GetPolicyInfo("*",exception);
331 if (p == (const PolicyInfo *) NULL)
332 return((char **) NULL);
333 policies=(char **) AcquireQuantumMemory((size_t)
334 GetNumberOfElementsInLinkedList(policy_list)+1UL,sizeof(*policies));
335 if (policies == (char **) NULL)
336 return((char **) NULL);
337 /*
338 Generate policy list.
339 */
cristyf84a1932010-01-03 18:00:18 +0000340 LockSemaphoreInfo(policy_semaphore);
cristy3ed852e2009-09-05 21:47:34 +0000341 ResetLinkedListIterator(policy_list);
342 p=(const PolicyInfo *) GetNextValueInLinkedList(policy_list);
343 for (i=0; p != (const PolicyInfo *) NULL; )
344 {
345 if ((p->stealth == MagickFalse) &&
346 (GlobExpression(p->name,pattern,MagickFalse) != MagickFalse))
347 policies[i++]=ConstantString(p->name);
348 p=(const PolicyInfo *) GetNextValueInLinkedList(policy_list);
349 }
cristyf84a1932010-01-03 18:00:18 +0000350 UnlockSemaphoreInfo(policy_semaphore);
cristy3ed852e2009-09-05 21:47:34 +0000351 policies[i]=(char *) NULL;
cristybb503372010-05-27 20:51:26 +0000352 *number_policies=(size_t) i;
cristy3ed852e2009-09-05 21:47:34 +0000353 return(policies);
354}
355
356/*
357%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
358% %
359% %
360% %
361% G e t P o l i c y V a l u e %
362% %
363% %
364% %
365%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
366%
367% GetPolicyValue() returns the value associated with the named policy.
368%
369% The format of the GetPolicyValue method is:
370%
371% char *GetPolicyValue(const char *name)
372%
373% A description of each parameter follows:
374%
375% o policy_info: The policy info.
376%
377*/
378MagickExport char *GetPolicyValue(const char *name)
379{
380 const char
381 *value;
382
383 const PolicyInfo
384 *policy_info;
385
386 ExceptionInfo
387 *exception;
388
389 assert(name != (const char *) NULL);
390 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",name);
391 exception=AcquireExceptionInfo();
392 policy_info=GetPolicyInfo(name,exception);
393 exception=DestroyExceptionInfo(exception);
394 if (policy_info == (PolicyInfo *) NULL)
395 return((char *) NULL);
396 value=policy_info->value;
397 if ((value == (const char *) NULL) || (*value == '\0'))
398 return((char *) NULL);
399 return(ConstantString(value));
400}
401
402/*
403%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
404% %
405% %
406% %
407+ I n i t i a l i z e P o l i c y L i s t %
408% %
409% %
410% %
411%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
412%
413% InitializePolicyList() initializes the policy list.
414%
415% The format of the InitializePolicyList method is:
416%
417% MagickBooleanType InitializePolicyList(ExceptionInfo *exception)
418%
419% A description of each parameter follows.
420%
421% o exception: return any errors or warnings in this structure.
422%
423*/
424static MagickBooleanType InitializePolicyList(ExceptionInfo *exception)
425{
426 if ((policy_list == (LinkedListInfo *) NULL) &&
427 (instantiate_policy == MagickFalse))
428 {
cristy4e1dff62009-10-25 20:36:03 +0000429 if (policy_semaphore == (SemaphoreInfo *) NULL)
430 AcquireSemaphoreInfo(&policy_semaphore);
cristyf84a1932010-01-03 18:00:18 +0000431 LockSemaphoreInfo(policy_semaphore);
cristy3ed852e2009-09-05 21:47:34 +0000432 if ((policy_list == (LinkedListInfo *) NULL) &&
433 (instantiate_policy == MagickFalse))
434 {
435 (void) LoadPolicyLists(PolicyFilename,exception);
436 instantiate_policy=MagickTrue;
437 }
cristyf84a1932010-01-03 18:00:18 +0000438 UnlockSemaphoreInfo(policy_semaphore);
cristy3ed852e2009-09-05 21:47:34 +0000439 }
440 return(policy_list != (LinkedListInfo *) NULL ? MagickTrue : MagickFalse);
441}
442
443/*
444%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
445% %
446% %
447% %
cristy3ed852e2009-09-05 21:47:34 +0000448% I s R i g h t s A u t h o r i z e d %
449% %
450% %
451% %
452%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
453%
454% IsRightsAuthorized() returns MagickTrue if the policy authorizes the
455% requested rights for the specified domain.
456%
457% The format of the IsRightsAuthorized method is:
458%
459% MagickBooleanType IsRightsAuthorized(const PolicyDomain domain,
460% const PolicyRights rights,const char *pattern)
461%
462% A description of each parameter follows:
463%
464% o domain: the policy domain.
465%
466% o rights: the policy rights.
467%
468% o pattern: the coder, delegate, filter, or path pattern.
469%
470*/
471MagickExport MagickBooleanType IsRightsAuthorized(const PolicyDomain domain,
472 const PolicyRights rights,const char *pattern)
473{
474 const PolicyInfo
475 *policy_info;
476
477 ExceptionInfo
478 *exception;
479
480 MagickBooleanType
481 authorized;
482
483 register PolicyInfo
484 *p;
485
486 (void) LogMagickEvent(PolicyEvent,GetMagickModule(),
487 "Domain: %s; rights=%s; pattern=\"%s\" ...",
cristy042ee782011-04-22 18:48:30 +0000488 CommandOptionToMnemonic(MagickPolicyDomainOptions,domain),
489 CommandOptionToMnemonic(MagickPolicyRightsOptions,rights),pattern);
cristy3ed852e2009-09-05 21:47:34 +0000490 exception=AcquireExceptionInfo();
491 policy_info=GetPolicyInfo("*",exception);
492 exception=DestroyExceptionInfo(exception);
493 if (policy_info == (PolicyInfo *) NULL)
494 return(MagickTrue);
495 authorized=MagickTrue;
cristyf84a1932010-01-03 18:00:18 +0000496 LockSemaphoreInfo(policy_semaphore);
cristy3ed852e2009-09-05 21:47:34 +0000497 ResetLinkedListIterator(policy_list);
498 p=(PolicyInfo *) GetNextValueInLinkedList(policy_list);
499 while ((p != (PolicyInfo *) NULL) && (authorized != MagickFalse))
500 {
501 if ((p->domain == domain) &&
502 (GlobExpression(pattern,p->pattern,MagickFalse) != MagickFalse))
503 {
504 if (((rights & ReadPolicyRights) != 0) &&
505 ((p->rights & ReadPolicyRights) == 0))
506 authorized=MagickFalse;
507 if (((rights & WritePolicyRights) != 0) &&
508 ((p->rights & WritePolicyRights) == 0))
509 authorized=MagickFalse;
510 if (((rights & ExecutePolicyRights) != 0) &&
511 ((p->rights & ExecutePolicyRights) == 0))
512 authorized=MagickFalse;
513 }
514 p=(PolicyInfo *) GetNextValueInLinkedList(policy_list);
515 }
cristyf84a1932010-01-03 18:00:18 +0000516 UnlockSemaphoreInfo(policy_semaphore);
cristy3ed852e2009-09-05 21:47:34 +0000517 return(authorized);
518}
519
520/*
521%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
522% %
523% %
524% %
525% L i s t P o l i c y I n f o %
526% %
527% %
528% %
529%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
530%
531% ListPolicyInfo() lists policies to the specified file.
532%
533% The format of the ListPolicyInfo method is:
534%
535% MagickBooleanType ListPolicyInfo(FILE *file,ExceptionInfo *exception)
536%
537% A description of each parameter follows.
538%
539% o file: List policy names to this file handle.
540%
541% o exception: return any errors or warnings in this structure.
542%
543*/
544MagickExport MagickBooleanType ListPolicyInfo(FILE *file,
545 ExceptionInfo *exception)
546{
547 const char
548 *path,
549 *domain;
550
551 const PolicyInfo
552 **policy_info;
553
cristybb503372010-05-27 20:51:26 +0000554 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +0000555 i;
556
cristybb503372010-05-27 20:51:26 +0000557 size_t
cristy3ed852e2009-09-05 21:47:34 +0000558 number_policies;
559
560 /*
561 List name and attributes of each policy in the list.
562 */
563 if (file == (const FILE *) NULL)
564 file=stdout;
565 policy_info=GetPolicyInfoList("*",&number_policies,exception);
566 if (policy_info == (const PolicyInfo **) NULL)
567 return(MagickFalse);
568 path=(const char *) NULL;
cristybb503372010-05-27 20:51:26 +0000569 for (i=0; i < (ssize_t) number_policies; i++)
cristy3ed852e2009-09-05 21:47:34 +0000570 {
571 if (policy_info[i]->stealth != MagickFalse)
572 continue;
573 if (((path == (const char *) NULL) ||
574 (LocaleCompare(path,policy_info[i]->path) != 0)) &&
575 (policy_info[i]->path != (char *) NULL))
cristyb51dff52011-05-19 16:55:47 +0000576 (void) FormatLocaleFile(file,"\nPath: %s\n",policy_info[i]->path);
cristy3ed852e2009-09-05 21:47:34 +0000577 path=policy_info[i]->path;
cristy042ee782011-04-22 18:48:30 +0000578 domain=CommandOptionToMnemonic(MagickPolicyDomainOptions,
cristy3ed852e2009-09-05 21:47:34 +0000579 policy_info[i]->domain);
cristyb51dff52011-05-19 16:55:47 +0000580 (void) FormatLocaleFile(file," Policy: %s\n",domain);
cristy7ce14bc2010-01-17 00:01:01 +0000581 if ((policy_info[i]->domain == ResourcePolicyDomain) ||
582 (policy_info[i]->domain == SystemPolicyDomain))
cristy3ed852e2009-09-05 21:47:34 +0000583 {
584 if (policy_info[i]->name != (char *) NULL)
cristyb51dff52011-05-19 16:55:47 +0000585 (void) FormatLocaleFile(file," name: %s\n",policy_info[i]->name);
cristy3ed852e2009-09-05 21:47:34 +0000586 if (policy_info[i]->value != (char *) NULL)
cristyb51dff52011-05-19 16:55:47 +0000587 (void) FormatLocaleFile(file," value: %s\n",policy_info[i]->value);
cristy3ed852e2009-09-05 21:47:34 +0000588 }
589 else
590 {
cristyb51dff52011-05-19 16:55:47 +0000591 (void) FormatLocaleFile(file," rights: ");
cristy3ed852e2009-09-05 21:47:34 +0000592 if (policy_info[i]->rights == NoPolicyRights)
cristyb51dff52011-05-19 16:55:47 +0000593 (void) FormatLocaleFile(file,"None ");
cristy3ed852e2009-09-05 21:47:34 +0000594 if ((policy_info[i]->rights & ReadPolicyRights) != 0)
cristyb51dff52011-05-19 16:55:47 +0000595 (void) FormatLocaleFile(file,"Read ");
cristy3ed852e2009-09-05 21:47:34 +0000596 if ((policy_info[i]->rights & WritePolicyRights) != 0)
cristyb51dff52011-05-19 16:55:47 +0000597 (void) FormatLocaleFile(file,"Write ");
cristy3ed852e2009-09-05 21:47:34 +0000598 if ((policy_info[i]->rights & ExecutePolicyRights) != 0)
cristyb51dff52011-05-19 16:55:47 +0000599 (void) FormatLocaleFile(file,"Execute ");
600 (void) FormatLocaleFile(file,"\n");
cristy3ed852e2009-09-05 21:47:34 +0000601 if (policy_info[i]->pattern != (char *) NULL)
cristy1e604812011-05-19 18:07:50 +0000602 (void) FormatLocaleFile(file," pattern: %s\n",
603 policy_info[i]->pattern);
cristy3ed852e2009-09-05 21:47:34 +0000604 }
605 }
606 policy_info=(const PolicyInfo **) RelinquishMagickMemory((void *)
607 policy_info);
608 (void) fflush(file);
609 return(MagickTrue);
610}
611
612/*
613%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
614% %
615% %
616% %
617+ L o a d P o l i c y L i s t %
618% %
619% %
620% %
621%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
622%
623% LoadPolicyList() loads the policy configuration file which provides a mapping
624% between policy attributes and a policy domain.
625%
626% The format of the LoadPolicyList method is:
627%
628% MagickBooleanType LoadPolicyList(const char *xml,const char *filename,
cristybb503372010-05-27 20:51:26 +0000629% const size_t depth,ExceptionInfo *exception)
cristy3ed852e2009-09-05 21:47:34 +0000630%
631% A description of each parameter follows:
632%
633% o xml: The policy list in XML format.
634%
635% o filename: The policy list filename.
636%
637% o depth: depth of <include /> statements.
638%
639% o exception: return any errors or warnings in this structure.
640%
641*/
642static MagickBooleanType LoadPolicyList(const char *xml,const char *filename,
cristybb503372010-05-27 20:51:26 +0000643 const size_t depth,ExceptionInfo *exception)
cristy3ed852e2009-09-05 21:47:34 +0000644{
645 char
646 keyword[MaxTextExtent],
647 *token;
648
649 PolicyInfo
650 *policy_info;
651
652 const char
653 *q;
654
655 MagickBooleanType
656 status;
657
658 /*
659 Load the policy map file.
660 */
661 (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),
662 "Loading policy file \"%s\" ...",filename);
663 if (xml == (char *) NULL)
664 return(MagickFalse);
665 if (policy_list == (LinkedListInfo *) NULL)
666 {
667 policy_list=NewLinkedList(0);
668 if (policy_list == (LinkedListInfo *) NULL)
669 {
670 ThrowFileException(exception,ResourceLimitError,
671 "MemoryAllocationFailed",filename);
672 return(MagickFalse);
673 }
674 }
675 status=MagickTrue;
676 policy_info=(PolicyInfo *) NULL;
677 token=AcquireString(xml);
678 for (q=(const char *) xml; *q != '\0'; )
679 {
680 /*
681 Interpret XML.
682 */
683 GetMagickToken(q,&q,token);
684 if (*token == '\0')
685 break;
686 (void) CopyMagickString(keyword,token,MaxTextExtent);
687 if (LocaleNCompare(keyword,"<!DOCTYPE",9) == 0)
688 {
689 /*
690 Docdomain element.
691 */
692 while ((LocaleNCompare(q,"]>",2) != 0) && (*q != '\0'))
693 GetMagickToken(q,&q,token);
694 continue;
695 }
696 if (LocaleNCompare(keyword,"<!--",4) == 0)
697 {
698 /*
699 Comment element.
700 */
701 while ((LocaleNCompare(q,"->",2) != 0) && (*q != '\0'))
702 GetMagickToken(q,&q,token);
703 continue;
704 }
705 if (LocaleCompare(keyword,"<include") == 0)
706 {
707 /*
708 Include element.
709 */
710 while (((*token != '/') && (*(token+1) != '>')) && (*q != '\0'))
711 {
712 (void) CopyMagickString(keyword,token,MaxTextExtent);
713 GetMagickToken(q,&q,token);
714 if (*token != '=')
715 continue;
716 GetMagickToken(q,&q,token);
717 if (LocaleCompare(keyword,"file") == 0)
718 {
719 if (depth > 200)
720 (void) ThrowMagickException(exception,GetMagickModule(),
721 ConfigureError,"IncludeElementNestedTooDeeply","`%s'",token);
722 else
723 {
724 char
725 path[MaxTextExtent],
726 *xml;
727
728 GetPathComponent(filename,HeadPath,path);
729 if (*path != '\0')
730 (void) ConcatenateMagickString(path,DirectorySeparator,
731 MaxTextExtent);
732 if (*token == *DirectorySeparator)
733 (void) CopyMagickString(path,token,MaxTextExtent);
734 else
735 (void) ConcatenateMagickString(path,token,MaxTextExtent);
736 xml=FileToString(path,~0,exception);
737 if (xml != (char *) NULL)
738 {
739 status=LoadPolicyList(xml,path,depth+1,exception);
740 xml=(char *) RelinquishMagickMemory(xml);
741 }
742 }
743 }
744 }
745 continue;
746 }
747 if (LocaleCompare(keyword,"<policy") == 0)
748 {
749 /*
750 Policy element.
751 */
cristy73bd4a52010-10-05 11:24:23 +0000752 policy_info=(PolicyInfo *) AcquireMagickMemory(sizeof(*policy_info));
cristy3ed852e2009-09-05 21:47:34 +0000753 if (policy_info == (PolicyInfo *) NULL)
754 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
755 (void) ResetMagickMemory(policy_info,0,sizeof(*policy_info));
756 policy_info->path=ConstantString(filename);
cristy54a531d2009-10-21 17:58:01 +0000757 policy_info->exempt=MagickFalse;
cristy3ed852e2009-09-05 21:47:34 +0000758 policy_info->signature=MagickSignature;
759 continue;
760 }
761 if (policy_info == (PolicyInfo *) NULL)
762 continue;
763 if (LocaleCompare(keyword,"/>") == 0)
764 {
765 status=AppendValueToLinkedList(policy_list,policy_info);
766 if (status == MagickFalse)
767 (void) ThrowMagickException(exception,GetMagickModule(),
768 ResourceLimitError,"MemoryAllocationFailed","`%s'",
769 policy_info->name);
770 policy_info=(PolicyInfo *) NULL;
771 }
772 GetMagickToken(q,(const char **) NULL,token);
773 if (*token != '=')
774 continue;
775 GetMagickToken(q,&q,token);
776 GetMagickToken(q,&q,token);
777 switch (*keyword)
778 {
779 case 'D':
780 case 'd':
781 {
782 if (LocaleCompare((char *) keyword,"domain") == 0)
783 {
cristy042ee782011-04-22 18:48:30 +0000784 policy_info->domain=(PolicyDomain) ParseCommandOption(
cristy3ed852e2009-09-05 21:47:34 +0000785 MagickPolicyDomainOptions,MagickTrue,token);
786 break;
787 }
788 break;
789 }
790 case 'N':
791 case 'n':
792 {
793 if (LocaleCompare((char *) keyword,"name") == 0)
794 {
795 policy_info->name=ConstantString(token);
796 break;
797 }
798 break;
799 }
800 case 'P':
801 case 'p':
802 {
803 if (LocaleCompare((char *) keyword,"pattern") == 0)
804 {
805 policy_info->pattern=ConstantString(token);
806 break;
807 }
808 break;
809 }
810 case 'R':
811 case 'r':
812 {
813 if (LocaleCompare((char *) keyword,"rights") == 0)
814 {
cristy042ee782011-04-22 18:48:30 +0000815 policy_info->rights=(PolicyRights) ParseCommandOption(
cristy3ed852e2009-09-05 21:47:34 +0000816 MagickPolicyRightsOptions,MagickTrue,token);
817 break;
818 }
819 break;
820 }
821 case 'S':
822 case 's':
823 {
824 if (LocaleCompare((char *) keyword,"stealth") == 0)
825 {
826 policy_info->stealth=IsMagickTrue(token);
827 break;
828 }
829 break;
830 }
831 case 'V':
832 case 'v':
833 {
834 if (LocaleCompare((char *) keyword,"value") == 0)
835 {
836 policy_info->value=ConstantString(token);
837 break;
838 }
839 break;
840 }
841 default:
842 break;
843 }
844 }
845 token=(char *) RelinquishMagickMemory(token);
846 return(status);
847}
848
849/*
850%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
851% %
852% %
853% %
854% L o a d P o l i c y L i s t s %
855% %
856% %
857% %
858%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
859%
860% LoadPolicyList() loads one or more policy configuration file which provides a
861% mapping between policy attributes and a policy name.
862%
863% The format of the LoadPolicyLists method is:
864%
865% MagickBooleanType LoadPolicyLists(const char *filename,
866% ExceptionInfo *exception)
867%
868% A description of each parameter follows:
869%
870% o filename: the font file name.
871%
872% o exception: return any errors or warnings in this structure.
873%
874*/
875static MagickBooleanType LoadPolicyLists(const char *filename,
876 ExceptionInfo *exception)
877{
cristy3ed852e2009-09-05 21:47:34 +0000878 const StringInfo
879 *option;
880
881 LinkedListInfo
882 *options;
883
884 MagickStatusType
885 status;
886
cristybb503372010-05-27 20:51:26 +0000887 register ssize_t
cristy54a531d2009-10-21 17:58:01 +0000888 i;
889
890 /*
891 Load built-in policy map.
892 */
cristy3ed852e2009-09-05 21:47:34 +0000893 status=MagickFalse;
cristy54a531d2009-10-21 17:58:01 +0000894 if (policy_list == (LinkedListInfo *) NULL)
895 {
896 policy_list=NewLinkedList(0);
897 if (policy_list == (LinkedListInfo *) NULL)
898 {
899 ThrowFileException(exception,ResourceLimitError,
900 "MemoryAllocationFailed",filename);
901 return(MagickFalse);
902 }
903 }
cristybb503372010-05-27 20:51:26 +0000904 for (i=0; i < (ssize_t) (sizeof(PolicyMap)/sizeof(*PolicyMap)); i++)
cristy54a531d2009-10-21 17:58:01 +0000905 {
906 PolicyInfo
907 *policy_info;
908
909 register const PolicyMapInfo
910 *p;
911
912 p=PolicyMap+i;
cristy73bd4a52010-10-05 11:24:23 +0000913 policy_info=(PolicyInfo *) AcquireMagickMemory(sizeof(*policy_info));
cristy54a531d2009-10-21 17:58:01 +0000914 if (policy_info == (PolicyInfo *) NULL)
915 {
916 (void) ThrowMagickException(exception,GetMagickModule(),
917 ResourceLimitError,"MemoryAllocationFailed","`%s'",policy_info->name);
918 continue;
919 }
920 (void) ResetMagickMemory(policy_info,0,sizeof(*policy_info));
921 policy_info->path=(char *) "[built-in]";
922 policy_info->domain=p->domain;
923 policy_info->rights=p->rights;
924 policy_info->name=(char *) p->name;
925 policy_info->pattern=(char *) p->pattern;
926 policy_info->value=(char *) p->value;
927 policy_info->exempt=MagickTrue;
928 policy_info->signature=MagickSignature;
929 status=AppendValueToLinkedList(policy_list,policy_info);
930 if (status == MagickFalse)
931 (void) ThrowMagickException(exception,GetMagickModule(),
932 ResourceLimitError,"MemoryAllocationFailed","`%s'",policy_info->name);
933 }
934 /*
935 Load external policy map.
936 */
cristy3ed852e2009-09-05 21:47:34 +0000937 options=GetConfigureOptions(filename,exception);
938 option=(const StringInfo *) GetNextValueInLinkedList(options);
939 while (option != (const StringInfo *) NULL)
940 {
941 status|=LoadPolicyList((const char *) GetStringInfoDatum(option),
942 GetStringInfoPath(option),0,exception);
943 option=(const StringInfo *) GetNextValueInLinkedList(options);
944 }
945 options=DestroyConfigureOptions(options);
cristy3ed852e2009-09-05 21:47:34 +0000946 return(status != 0 ? MagickTrue : MagickFalse);
cristy3ed852e2009-09-05 21:47:34 +0000947}
cristyf34a1452009-10-24 22:29:27 +0000948
949/*
950%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
951% %
952% %
953% %
954+ P o l i c y C o m p o n e n t G e n e s i s %
955% %
956% %
957% %
958%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
959%
960% PolicyComponentGenesis() instantiates the policy component.
961%
962% The format of the PolicyComponentGenesis method is:
963%
964% MagickBooleanType PolicyComponentGenesis(void)
965%
966*/
cristy5ff4eaf2011-09-03 01:38:02 +0000967MagickPrivate MagickBooleanType PolicyComponentGenesis(void)
cristyf34a1452009-10-24 22:29:27 +0000968{
cristy165b6092009-10-26 13:52:10 +0000969 AcquireSemaphoreInfo(&policy_semaphore);
cristyf34a1452009-10-24 22:29:27 +0000970 return(MagickTrue);
971}
972
973/*
974%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
975% %
976% %
977% %
978+ P o l i c y C o m p o n e n t T e r m i n u s %
979% %
980% %
981% %
982%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
983%
984% PolicyComponentTerminus() destroys the policy component.
985%
986% The format of the PolicyComponentTerminus method is:
987%
988% PolicyComponentTerminus(void)
989%
990*/
991
992static void *DestroyPolicyElement(void *policy_info)
993{
994 register PolicyInfo
995 *p;
996
997 p=(PolicyInfo *) policy_info;
998 if (p->exempt == MagickFalse)
999 {
1000 if (p->value != (char *) NULL)
1001 p->value=DestroyString(p->value);
1002 if (p->pattern != (char *) NULL)
1003 p->pattern=DestroyString(p->pattern);
1004 if (p->name != (char *) NULL)
1005 p->name=DestroyString(p->name);
1006 if (p->path != (char *) NULL)
1007 p->path=DestroyString(p->path);
1008 }
1009 p=(PolicyInfo *) RelinquishMagickMemory(p);
1010 return((void *) NULL);
1011}
1012
cristy5ff4eaf2011-09-03 01:38:02 +00001013MagickPrivate void PolicyComponentTerminus(void)
cristyf34a1452009-10-24 22:29:27 +00001014{
cristy18b17442009-10-25 18:36:48 +00001015 if (policy_semaphore == (SemaphoreInfo *) NULL)
1016 AcquireSemaphoreInfo(&policy_semaphore);
cristyf84a1932010-01-03 18:00:18 +00001017 LockSemaphoreInfo(policy_semaphore);
cristyf34a1452009-10-24 22:29:27 +00001018 if (policy_list != (LinkedListInfo *) NULL)
1019 policy_list=DestroyLinkedList(policy_list,DestroyPolicyElement);
1020 instantiate_policy=MagickFalse;
cristyf84a1932010-01-03 18:00:18 +00001021 UnlockSemaphoreInfo(policy_semaphore);
cristyf34a1452009-10-24 22:29:27 +00001022 DestroySemaphoreInfo(&policy_semaphore);
1023}