MagickCore  7.0.11
policy.c
Go to the documentation of this file.
1 /*
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 % Cristy %
16 % July 1992 %
17 % %
18 % %
19 % Copyright 1999-2021 ImageMagick Studio LLC, a non-profit organization %
20 % 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 % https://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 */
43 #include "MagickCore/studio.h"
45 #include "MagickCore/client.h"
46 #include "MagickCore/configure.h"
48 #include "MagickCore/exception.h"
51 #include "MagickCore/memory_.h"
53 #include "MagickCore/monitor.h"
55 #include "MagickCore/option.h"
56 #include "MagickCore/policy.h"
58 #include "MagickCore/resource_.h"
60 #include "MagickCore/semaphore.h"
62 #include "MagickCore/string_.h"
64 #include "MagickCore/token.h"
65 #include "MagickCore/utility.h"
67 #include "MagickCore/xml-tree.h"
69 
70 /*
71  Define declarations.
72 */
73 #define PolicyFilename "policy.xml"
74 
75 /*
76  Typedef declarations.
77 */
79 {
80  char
81  *path;
82 
85 
88 
89  char
90  *name,
91  *pattern,
92  *value;
93 
96  stealth,
97  debug;
98 
101 
102  size_t
104 };
105 
106 typedef struct _PolicyMapInfo
107 {
108  const PolicyDomain
110 
111  const PolicyRights
113 
114  const char
116  *pattern,
117  *value;
118 } PolicyMapInfo;
119 
120 /*
121  Static declarations.
122 */
123 static const PolicyMapInfo
125  {
126  { UndefinedPolicyDomain, UndefinedPolicyRights, (const char *) NULL,
127  (const char *) NULL, (const char *) NULL }
128  };
129 
130 static LinkedListInfo
132 
133 static SemaphoreInfo
135 
136 /*
137  Forward declarations.
138 */
139 static MagickBooleanType
141  LoadPolicyCache(LinkedListInfo *,const char *,const char *,const size_t,
142  ExceptionInfo *);
143 
144 /*
145 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
146 % %
147 % %
148 % %
149 % A c q u i r e P o l i c y C a c h e %
150 % %
151 % %
152 % %
153 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
154 %
155 % AcquirePolicyCache() caches one or more policy configurations which provides
156 % a mapping between policy attributes and a policy name.
157 %
158 % The format of the AcquirePolicyCache method is:
159 %
160 % LinkedListInfo *AcquirePolicyCache(const char *filename,
161 % ExceptionInfo *exception)
162 %
163 % A description of each parameter follows:
164 %
165 % o filename: the policy configuration file name.
166 %
167 % o exception: return any errors or warnings in this structure.
168 %
169 */
170 static LinkedListInfo *AcquirePolicyCache(const char *filename,
171  ExceptionInfo *exception)
172 {
174  *cache;
175 
177  status;
178 
179  ssize_t
180  i;
181 
182  /*
183  Load external policy map.
184  */
185  cache=NewLinkedList(0);
186  status=MagickTrue;
187 #if MAGICKCORE_ZERO_CONFIGURATION_SUPPORT
188  (void) filename;
189  status=LoadPolicyCache(cache,ZeroConfigurationPolicy,"[zero-configuration]",0,
190  exception);
191 #else
192  {
193  const StringInfo
194  *option;
195 
197  *options;
198 
199  options=GetConfigureOptions(filename,exception);
200  option=(const StringInfo *) GetNextValueInLinkedList(options);
201  while (option != (const StringInfo *) NULL)
202  {
203  status&=LoadPolicyCache(cache,(const char *) GetStringInfoDatum(option),
204  GetStringInfoPath(option),0,exception);
205  option=(const StringInfo *) GetNextValueInLinkedList(options);
206  }
207  options=DestroyConfigureOptions(options);
208  }
209 #endif
210  /*
211  Load built-in policy map.
212  */
213  for (i=0; i < (ssize_t) (sizeof(PolicyMap)/sizeof(*PolicyMap)); i++)
214  {
215  PolicyInfo
216  *policy_info;
217 
218  const PolicyMapInfo
219  *p;
220 
221  p=PolicyMap+i;
222  policy_info=(PolicyInfo *) AcquireMagickMemory(sizeof(*policy_info));
223  if (policy_info == (PolicyInfo *) NULL)
224  {
225  (void) ThrowMagickException(exception,GetMagickModule(),
226  ResourceLimitError,"MemoryAllocationFailed","`%s'",
227  p->name == (char *) NULL ? "" : p->name);
228  continue;
229  }
230  (void) memset(policy_info,0,sizeof(*policy_info));
231  policy_info->path=(char *) "[built-in]";
232  policy_info->domain=p->domain;
233  policy_info->rights=p->rights;
234  policy_info->name=(char *) p->name;
235  policy_info->pattern=(char *) p->pattern;
236  policy_info->value=(char *) p->value;
237  policy_info->exempt=MagickTrue;
238  policy_info->signature=MagickCoreSignature;
239  status&=AppendValueToLinkedList(cache,policy_info);
240  if (status == MagickFalse)
241  (void) ThrowMagickException(exception,GetMagickModule(),
242  ResourceLimitError,"MemoryAllocationFailed","`%s'",policy_info->name);
243  }
244  return(cache);
245 }
246 
247 /*
248 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
249 % %
250 % %
251 % %
252 + G e t P o l i c y I n f o %
253 % %
254 % %
255 % %
256 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
257 %
258 % GetPolicyInfo() searches the policy list for the specified name and if found
259 % returns attributes for that policy.
260 %
261 % The format of the GetPolicyInfo method is:
262 %
263 % PolicyInfo *GetPolicyInfo(const char *name,ExceptionInfo *exception)
264 %
265 % A description of each parameter follows:
266 %
267 % o name: the policy name.
268 %
269 % o exception: return any errors or warnings in this structure.
270 %
271 */
272 static PolicyInfo *GetPolicyInfo(const char *name,ExceptionInfo *exception)
273 {
274  char
275  policyname[MagickPathExtent];
276 
278  domain;
279 
280  PolicyInfo
281  *p;
282 
283  char
284  *q;
285 
286  assert(exception != (ExceptionInfo *) NULL);
287  if (IsPolicyCacheInstantiated(exception) == MagickFalse)
288  return((PolicyInfo *) NULL);
289  /*
290  Strip names of whitespace.
291  */
292  *policyname='\0';
293  if (name != (const char *) NULL)
294  (void) CopyMagickString(policyname,name,MagickPathExtent);
295  for (q=policyname; *q != '\0'; q++)
296  {
297  if (isspace((int) ((unsigned char) *q)) == 0)
298  continue;
299  (void) CopyMagickString(q,q+1,MagickPathExtent);
300  q--;
301  }
302  /*
303  Strip domain from policy name (e.g. resource:map).
304  */
305  domain=UndefinedPolicyDomain;
306  for (q=policyname; *q != '\0'; q++)
307  {
308  if (*q != ':')
309  continue;
310  *q='\0';
312  MagickTrue,policyname);
313  (void) CopyMagickString(policyname,q+1,MagickPathExtent);
314  break;
315  }
316  /*
317  Search for policy tag.
318  */
322  if ((name == (const char *) NULL) || (LocaleCompare(name,"*") == 0))
323  {
325  return(p);
326  }
327  while (p != (PolicyInfo *) NULL)
328  {
329  if ((domain == UndefinedPolicyDomain) || (p->domain == domain))
330  if (LocaleCompare(policyname,p->name) == 0)
331  break;
333  }
334  if (p != (PolicyInfo *) NULL)
338  return(p);
339 }
340 
341 /*
342 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
343 % %
344 % %
345 % %
346 % G e t P o l i c y I n f o L i s t %
347 % %
348 % %
349 % %
350 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
351 %
352 % GetPolicyInfoList() returns any policies that match the specified pattern.
353 %
354 % The format of the GetPolicyInfoList function is:
355 %
356 % const PolicyInfo **GetPolicyInfoList(const char *pattern,
357 % size_t *number_policies,ExceptionInfo *exception)
358 %
359 % A description of each parameter follows:
360 %
361 % o pattern: Specifies a pointer to a text string containing a pattern.
362 %
363 % o number_policies: returns the number of policies in the list.
364 %
365 % o exception: return any errors or warnings in this structure.
366 %
367 */
368 MagickExport const PolicyInfo **GetPolicyInfoList(const char *pattern,
369  size_t *number_policies,ExceptionInfo *exception)
370 {
371  const PolicyInfo
372  **policies;
373 
374  const PolicyInfo
375  *p;
376 
377  ssize_t
378  i;
379 
380  /*
381  Allocate policy list.
382  */
383  assert(pattern != (char *) NULL);
384  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",pattern);
385  assert(number_policies != (size_t *) NULL);
386  *number_policies=0;
387  p=GetPolicyInfo("*",exception);
388  if (p == (const PolicyInfo *) NULL)
389  return((const PolicyInfo **) NULL);
390  policies=(const PolicyInfo **) AcquireQuantumMemory((size_t)
391  GetNumberOfElementsInLinkedList(policy_cache)+1UL,sizeof(*policies));
392  if (policies == (const PolicyInfo **) NULL)
393  return((const PolicyInfo **) NULL);
394  /*
395  Generate policy list.
396  */
400  for (i=0; p != (const PolicyInfo *) NULL; )
401  {
402  if ((p->stealth == MagickFalse) &&
403  (GlobExpression(p->name,pattern,MagickFalse) != MagickFalse))
404  policies[i++]=p;
406  }
408  policies[i]=(PolicyInfo *) NULL;
409  *number_policies=(size_t) i;
410  return(policies);
411 }
412 
413 /*
414 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
415 % %
416 % %
417 % %
418 % G e t P o l i c y L i s t %
419 % %
420 % %
421 % %
422 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
423 %
424 % GetPolicyList() returns any policies that match the specified pattern.
425 %
426 % The format of the GetPolicyList function is:
427 %
428 % char **GetPolicyList(const char *pattern,size_t *number_policies,
429 % ExceptionInfo *exception)
430 %
431 % A description of each parameter follows:
432 %
433 % o pattern: a pointer to a text string containing a pattern.
434 %
435 % o number_policies: returns the number of policies in the list.
436 %
437 % o exception: return any errors or warnings in this structure.
438 %
439 */
440 
441 static char *AcquirePolicyString(const char *source,const size_t pad)
442 {
443  char
444  *destination;
445 
446  size_t
447  length;
448 
449  length=0;
450  if (source != (char *) NULL)
451  length+=strlen(source);
452  destination=(char *) NULL;
453  /* AcquireMagickMemory needs to be used here to avoid an omp deadlock */
454  if (~length >= pad)
455  destination=(char *) AcquireMagickMemory((length+pad)*sizeof(*destination));
456  if (destination == (char *) NULL)
457  ThrowFatalException(ResourceLimitFatalError,"UnableToAcquireString");
458  if (source != (char *) NULL)
459  (void) memcpy(destination,source,length*sizeof(*destination));
460  destination[length]='\0';
461  return(destination);
462 }
463 
464 MagickExport char **GetPolicyList(const char *pattern,size_t *number_policies,
465  ExceptionInfo *exception)
466 {
467  char
468  **policies;
469 
470  const PolicyInfo
471  *p;
472 
473  ssize_t
474  i;
475 
476  /*
477  Allocate policy list.
478  */
479  assert(pattern != (char *) NULL);
480  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",pattern);
481  assert(number_policies != (size_t *) NULL);
482  *number_policies=0;
483  p=GetPolicyInfo("*",exception);
484  if (p == (const PolicyInfo *) NULL)
485  return((char **) NULL);
486  policies=(char **) AcquireQuantumMemory((size_t)
487  GetNumberOfElementsInLinkedList(policy_cache)+1UL,sizeof(*policies));
488  if (policies == (char **) NULL)
489  return((char **) NULL);
490  /*
491  Generate policy list.
492  */
496  for (i=0; p != (const PolicyInfo *) NULL; )
497  {
498  if ((p->stealth == MagickFalse) &&
499  (GlobExpression(p->name,pattern,MagickFalse) != MagickFalse))
500  policies[i++]=AcquirePolicyString(p->name,1);
502  }
504  policies[i]=(char *) NULL;
505  *number_policies=(size_t) i;
506  return(policies);
507 }
508 
509 /*
510 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
511 % %
512 % %
513 % %
514 % G e t P o l i c y V a l u e %
515 % %
516 % %
517 % %
518 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
519 %
520 % GetPolicyValue() returns the value associated with the named policy.
521 %
522 % The format of the GetPolicyValue method is:
523 %
524 % char *GetPolicyValue(const char *name)
525 %
526 % A description of each parameter follows:
527 %
528 % o name: The name of the policy.
529 %
530 */
531 MagickExport char *GetPolicyValue(const char *name)
532 {
533  const char
534  *value;
535 
536  const PolicyInfo
537  *policy_info;
538 
540  *exception;
541 
542  assert(name != (const char *) NULL);
543  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",name);
544  exception=AcquireExceptionInfo();
545  policy_info=GetPolicyInfo(name,exception);
546  exception=DestroyExceptionInfo(exception);
547  if (policy_info == (PolicyInfo *) NULL)
548  return((char *) NULL);
549  value=policy_info->value;
550  if ((value == (const char *) NULL) || (*value == '\0'))
551  return((char *) NULL);
552  return(AcquirePolicyString(value,1));
553 }
554 
555 /*
556 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
557 % %
558 % %
559 % %
560 + I s P o l i c y C a c h e I n s t a n t i a t e d %
561 % %
562 % %
563 % %
564 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
565 %
566 % IsPolicyCacheInstantiated() determines if the policy list is instantiated.
567 % If not, it instantiates the list and returns it.
568 %
569 % The format of the IsPolicyInstantiated method is:
570 %
571 % MagickBooleanType IsPolicyCacheInstantiated(ExceptionInfo *exception)
572 %
573 % A description of each parameter follows.
574 %
575 % o exception: return any errors or warnings in this structure.
576 %
577 */
579 {
580  if (policy_cache == (LinkedListInfo *) NULL)
581  {
582  if (policy_semaphore == (SemaphoreInfo *) NULL)
585  if (policy_cache == (LinkedListInfo *) NULL)
588  }
589  return(policy_cache != (LinkedListInfo *) NULL ? MagickTrue : MagickFalse);
590 }
591 
592 /*
593 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
594 % %
595 % %
596 % %
597 % I s R i g h t s A u t h o r i z e d %
598 % %
599 % %
600 % %
601 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
602 %
603 % IsRightsAuthorized() returns MagickTrue if the policy authorizes the
604 % requested rights for the specified domain.
605 %
606 % The format of the IsRightsAuthorized method is:
607 %
608 % MagickBooleanType IsRightsAuthorized(const PolicyDomain domain,
609 % const PolicyRights rights,const char *pattern)
610 %
611 % A description of each parameter follows:
612 %
613 % o domain: the policy domain.
614 %
615 % o rights: the policy rights.
616 %
617 % o pattern: the coder, delegate, filter, or path pattern.
618 %
619 */
621  const PolicyRights rights,const char *pattern)
622 {
623  const PolicyInfo
624  *policy_info;
625 
627  *exception;
628 
630  authorized;
631 
632  PolicyInfo
633  *p;
634 
635  if (IsEventLogging() != MagickFalse)
637  "Domain: %s; rights=%s; pattern=\"%s\" ...",
640  exception=AcquireExceptionInfo();
641  policy_info=GetPolicyInfo("*",exception);
642  exception=DestroyExceptionInfo(exception);
643  if (policy_info == (PolicyInfo *) NULL)
644  return(MagickTrue);
645  authorized=MagickTrue;
649  while (p != (PolicyInfo *) NULL)
650  {
651  if ((p->domain == domain) &&
653  {
654  if ((rights & ReadPolicyRights) != 0)
655  authorized=(p->rights & ReadPolicyRights) != 0 ? MagickTrue :
656  MagickFalse;
657  if ((rights & WritePolicyRights) != 0)
658  authorized=(p->rights & WritePolicyRights) != 0 ? MagickTrue :
659  MagickFalse;
660  if ((rights & ExecutePolicyRights) != 0)
661  authorized=(p->rights & ExecutePolicyRights) != 0 ? MagickTrue :
662  MagickFalse;
663  }
665  }
667  return(authorized);
668 }
669 
670 /*
671 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
672 % %
673 % %
674 % %
675 % L i s t P o l i c y I n f o %
676 % %
677 % %
678 % %
679 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
680 %
681 % ListPolicyInfo() lists policies to the specified file.
682 %
683 % The format of the ListPolicyInfo method is:
684 %
685 % MagickBooleanType ListPolicyInfo(FILE *file,ExceptionInfo *exception)
686 %
687 % A description of each parameter follows.
688 %
689 % o file: List policy names to this file handle.
690 %
691 % o exception: return any errors or warnings in this structure.
692 %
693 */
695  ExceptionInfo *exception)
696 {
697  const char
698  *path,
699  *domain;
700 
701  const PolicyInfo
702  **policy_info;
703 
704  ssize_t
705  i;
706 
707  size_t
708  number_policies;
709 
710  /*
711  List name and attributes of each policy in the list.
712  */
713  if (file == (const FILE *) NULL)
714  file=stdout;
715  policy_info=GetPolicyInfoList("*",&number_policies,exception);
716  if (policy_info == (const PolicyInfo **) NULL)
717  return(MagickFalse);
718  path=(const char *) NULL;
719  for (i=0; i < (ssize_t) number_policies; i++)
720  {
721  if (policy_info[i]->stealth != MagickFalse)
722  continue;
723  if (((path == (const char *) NULL) ||
724  (LocaleCompare(path,policy_info[i]->path) != 0)) &&
725  (policy_info[i]->path != (char *) NULL))
726  (void) FormatLocaleFile(file,"\nPath: %s\n",policy_info[i]->path);
727  path=policy_info[i]->path;
729  policy_info[i]->domain);
730  (void) FormatLocaleFile(file," Policy: %s\n",domain);
731  if ((policy_info[i]->domain == CachePolicyDomain) ||
732  (policy_info[i]->domain == ResourcePolicyDomain) ||
733  (policy_info[i]->domain == SystemPolicyDomain))
734  {
735  if (policy_info[i]->name != (char *) NULL)
736  (void) FormatLocaleFile(file," name: %s\n",policy_info[i]->name);
737  if (policy_info[i]->value != (char *) NULL)
738  (void) FormatLocaleFile(file," value: %s\n",policy_info[i]->value);
739  }
740  else
741  {
742  (void) FormatLocaleFile(file," rights: ");
743  if (policy_info[i]->rights == NoPolicyRights)
744  (void) FormatLocaleFile(file,"None ");
745  if ((policy_info[i]->rights & ReadPolicyRights) != 0)
746  (void) FormatLocaleFile(file,"Read ");
747  if ((policy_info[i]->rights & WritePolicyRights) != 0)
748  (void) FormatLocaleFile(file,"Write ");
749  if ((policy_info[i]->rights & ExecutePolicyRights) != 0)
750  (void) FormatLocaleFile(file,"Execute ");
751  (void) FormatLocaleFile(file,"\n");
752  if (policy_info[i]->pattern != (char *) NULL)
753  (void) FormatLocaleFile(file," pattern: %s\n",
754  policy_info[i]->pattern);
755  }
756  }
757  policy_info=(const PolicyInfo **) RelinquishMagickMemory((void *)
758  policy_info);
759  (void) fflush(file);
760  return(MagickTrue);
761 }
762 
763 /*
764 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
765 % %
766 % %
767 % %
768 + L o a d P o l i c y C a c h e %
769 % %
770 % %
771 % %
772 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
773 %
774 % LoadPolicyCache() loads the policy configurations which provides a mapping
775 % between policy attributes and a policy domain.
776 %
777 % The format of the LoadPolicyCache method is:
778 %
779 % MagickBooleanType LoadPolicyCache(LinkedListInfo *cache,const char *xml,
780 % const char *filename,const size_t depth,ExceptionInfo *exception)
781 %
782 % A description of each parameter follows:
783 %
784 % o xml: The policy list in XML format.
785 %
786 % o filename: The policy list filename.
787 %
788 % o depth: depth of <include /> statements.
789 %
790 % o exception: return any errors or warnings in this structure.
791 %
792 */
793 static MagickBooleanType LoadPolicyCache(LinkedListInfo *cache,const char *xml,
794  const char *filename,const size_t depth,ExceptionInfo *exception)
795 {
796  char
797  keyword[MagickPathExtent],
798  *token;
799 
800  const char
801  *q;
802 
804  status;
805 
806  PolicyInfo
807  *policy_info;
808 
809  size_t
810  extent;
811 
812  /*
813  Load the policy map file.
814  */
816  "Loading policy file \"%s\" ...",filename);
817  if (xml == (char *) NULL)
818  return(MagickFalse);
819  status=MagickTrue;
820  policy_info=(PolicyInfo *) NULL;
822  extent=strlen(token)+MagickPathExtent;
823  for (q=(const char *) xml; *q != '\0'; )
824  {
825  /*
826  Interpret XML.
827  */
828  (void) GetNextToken(q,&q,extent,token);
829  if (*token == '\0')
830  break;
831  (void) CopyMagickString(keyword,token,MagickPathExtent);
832  if (LocaleNCompare(keyword,"<!DOCTYPE",9) == 0)
833  {
834  /*
835  Docdomain element.
836  */
837  while ((LocaleNCompare(q,"]>",2) != 0) && (*q != '\0'))
838  (void) GetNextToken(q,&q,extent,token);
839  continue;
840  }
841  if (LocaleNCompare(keyword,"<!--",4) == 0)
842  {
843  /*
844  Comment element.
845  */
846  while ((LocaleNCompare(q,"->",2) != 0) && (*q != '\0'))
847  (void) GetNextToken(q,&q,extent,token);
848  continue;
849  }
850  if (LocaleCompare(keyword,"<include") == 0)
851  {
852  /*
853  Include element.
854  */
855  while (((*token != '/') && (*(token+1) != '>')) && (*q != '\0'))
856  {
857  (void) CopyMagickString(keyword,token,MagickPathExtent);
858  (void) GetNextToken(q,&q,extent,token);
859  if (*token != '=')
860  continue;
861  (void) GetNextToken(q,&q,extent,token);
862  if (LocaleCompare(keyword,"file") == 0)
863  {
864  if (depth > MagickMaxRecursionDepth)
865  (void) ThrowMagickException(exception,GetMagickModule(),
866  ConfigureError,"IncludeElementNestedTooDeeply","`%s'",token);
867  else
868  {
869  char
870  path[MagickPathExtent],
871  *file_xml;
872 
873  GetPathComponent(filename,HeadPath,path);
874  if (*path != '\0')
877  if (*token == *DirectorySeparator)
878  (void) CopyMagickString(path,token,MagickPathExtent);
879  else
880  (void) ConcatenateMagickString(path,token,MagickPathExtent);
881  file_xml=FileToXML(path,~0UL);
882  if (file_xml != (char *) NULL)
883  {
884  status&=LoadPolicyCache(cache,file_xml,path,
885  depth+1,exception);
886  file_xml=DestroyString(file_xml);
887  }
888  }
889  }
890  }
891  continue;
892  }
893  if (LocaleCompare(keyword,"<policy") == 0)
894  {
895  /*
896  Policy element.
897  */
898  policy_info=(PolicyInfo *) AcquireCriticalMemory(sizeof(*policy_info));
899  (void) memset(policy_info,0,sizeof(*policy_info));
900  policy_info->path=AcquirePolicyString(filename,1);
901  policy_info->exempt=MagickFalse;
902  policy_info->signature=MagickCoreSignature;
903  continue;
904  }
905  if (policy_info == (PolicyInfo *) NULL)
906  continue;
907  if ((LocaleCompare(keyword,"/>") == 0) ||
908  (LocaleCompare(keyword,"</policy>") == 0))
909  {
910  status=AppendValueToLinkedList(cache,policy_info);
911  if (status == MagickFalse)
912  (void) ThrowMagickException(exception,GetMagickModule(),
913  ResourceLimitError,"MemoryAllocationFailed","`%s'",
914  policy_info->name);
915  policy_info=(PolicyInfo *) NULL;
916  continue;
917  }
918  (void) GetNextToken(q,(const char **) NULL,extent,token);
919  if (*token != '=')
920  continue;
921  (void) GetNextToken(q,&q,extent,token);
922  (void) GetNextToken(q,&q,extent,token);
923  switch (*keyword)
924  {
925  case 'D':
926  case 'd':
927  {
928  if (LocaleCompare((char *) keyword,"domain") == 0)
929  {
930  policy_info->domain=(PolicyDomain) ParseCommandOption(
932  break;
933  }
934  break;
935  }
936  case 'N':
937  case 'n':
938  {
939  if (LocaleCompare((char *) keyword,"name") == 0)
940  {
941  policy_info->name=AcquirePolicyString(token,1);
942  break;
943  }
944  break;
945  }
946  case 'P':
947  case 'p':
948  {
949  if (LocaleCompare((char *) keyword,"pattern") == 0)
950  {
951  policy_info->pattern=AcquirePolicyString(token,1);
952  break;
953  }
954  break;
955  }
956  case 'R':
957  case 'r':
958  {
959  if (LocaleCompare((char *) keyword,"rights") == 0)
960  {
961  policy_info->rights=(PolicyRights) ParseCommandOption(
963  break;
964  }
965  break;
966  }
967  case 'S':
968  case 's':
969  {
970  if (LocaleCompare((char *) keyword,"stealth") == 0)
971  {
972  policy_info->stealth=IsStringTrue(token);
973  break;
974  }
975  break;
976  }
977  case 'V':
978  case 'v':
979  {
980  if (LocaleCompare((char *) keyword,"value") == 0)
981  {
982  policy_info->value=AcquirePolicyString(token,1);
983  break;
984  }
985  break;
986  }
987  default:
988  break;
989  }
990  }
991  token=(char *) RelinquishMagickMemory(token);
992  return(status != 0 ? MagickTrue : MagickFalse);
993 }
994 
995 /*
996 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
997 % %
998 % %
999 % %
1000 + P o l i c y C o m p o n e n t G e n e s i s %
1001 % %
1002 % %
1003 % %
1004 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1005 %
1006 % PolicyComponentGenesis() instantiates the policy component.
1007 %
1008 % The format of the PolicyComponentGenesis method is:
1009 %
1010 % MagickBooleanType PolicyComponentGenesis(void)
1011 %
1012 */
1014 {
1015  if (policy_semaphore == (SemaphoreInfo *) NULL)
1017  return(MagickTrue);
1018 }
1019 
1020 /*
1021 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1022 % %
1023 % %
1024 % %
1025 + P o l i c y C o m p o n e n t T e r m i n u s %
1026 % %
1027 % %
1028 % %
1029 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1030 %
1031 % PolicyComponentTerminus() destroys the policy component.
1032 %
1033 % The format of the PolicyComponentTerminus method is:
1034 %
1035 % PolicyComponentTerminus(void)
1036 %
1037 */
1038 
1039 static void *DestroyPolicyElement(void *policy_info)
1040 {
1041  PolicyInfo
1042  *p;
1043 
1044  p=(PolicyInfo *) policy_info;
1045  if (p->exempt == MagickFalse)
1046  {
1047  if (p->value != (char *) NULL)
1048  p->value=DestroyString(p->value);
1049  if (p->pattern != (char *) NULL)
1050  p->pattern=DestroyString(p->pattern);
1051  if (p->name != (char *) NULL)
1052  p->name=DestroyString(p->name);
1053  if (p->path != (char *) NULL)
1054  p->path=DestroyString(p->path);
1055  }
1057  return((void *) NULL);
1058 }
1059 
1061 {
1062  if (policy_semaphore == (SemaphoreInfo *) NULL)
1065  if (policy_cache != (LinkedListInfo *) NULL)
1069 }
1070 
1071 /*
1072 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1073 % %
1074 % %
1075 % %
1076 % S e t M a g i c k S e c u r i t y P o l i c y %
1077 % %
1078 % %
1079 % %
1080 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1081 %
1082 % SetMagickSecurityPolicy() sets the ImageMagick security policy. It returns
1083 % MagickFalse if the policy is already set or if the policy does not parse.
1084 %
1085 % The format of the SetMagickSecurityPolicy method is:
1086 %
1087 % MagickBooleanType SetMagickSecurityPolicy(const char *policy,
1088 % ExceptionInfo *exception)
1089 %
1090 % A description of each parameter follows:
1091 %
1092 % o policy: the security policy in the XML format.
1093 %
1094 % o exception: return any errors or warnings in this structure.
1095 %
1096 */
1098  ExceptionInfo *exception)
1099 {
1100  PolicyInfo
1101  *p;
1102 
1104  status;
1105 
1106  assert(exception != (ExceptionInfo *) NULL);
1107  if (policy == (const char *) NULL)
1108  return(MagickFalse);
1109  if (IsPolicyCacheInstantiated(exception) == MagickFalse)
1110  return(MagickFalse);
1114  if ((p != (PolicyInfo *) NULL) && (p->domain != UndefinedPolicyDomain))
1115  {
1117  return(MagickFalse);
1118  }
1120  status=LoadPolicyCache(policy_cache,policy,"[user-policy]",0,exception);
1121  if (status == MagickFalse)
1122  return(MagickFalse);
1123  return(ResourceComponentGenesis());
1124 }
1125 
1126 /*
1127 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1128 % %
1129 % %
1130 % %
1131 % S e t M a g i c k S e c u r i t y P o l i c y V a l u e %
1132 % %
1133 % %
1134 % %
1135 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1136 %
1137 % SetMagickSecurityPolicyValue() sets a value associated with an ImageMagick
1138 % security policy. For most policies, the value must be less than any value
1139 % set by the security policy configuration file (i.e. policy.xml). It returns
1140 % MagickFalse if the policy cannot be modified or if the policy does not parse.
1141 %
1142 % The format of the SetMagickSecurityPolicyValue method is:
1143 %
1144 % MagickBooleanType SetMagickSecurityPolicyValue(
1145 % const PolicyDomain domain,const char *name,const char *value,
1146 % ExceptionInfo *exception)
1147 %
1148 % A description of each parameter follows:
1149 %
1150 % o domain: the domain of the policy (e.g. system, resource).
1151 %
1152 % o name: the name of the policy.
1153 %
1154 % o value: the value to set the policy to.
1155 %
1156 % o exception: return any errors or warnings in this structure.
1157 %
1158 */
1159 
1161  const char *name,const char *value)
1162 {
1164  status;
1165 
1166  PolicyInfo
1167  *p;
1168 
1169  status=MagickTrue;
1173  while (p != (PolicyInfo *) NULL)
1174  {
1175  if ((p->domain == domain) && (LocaleCompare(name,p->name) == 0))
1176  break;
1178  }
1179  if (p != (PolicyInfo *) NULL)
1180  {
1181  if (p->value != (char *) NULL)
1182  p->value=DestroyString(p->value);
1183  }
1184  else
1185  {
1186  p=(PolicyInfo *) AcquireCriticalMemory(sizeof(*p));
1187  (void) memset(p,0,sizeof(*p));
1188  p->exempt=MagickFalse;
1190  p->domain=domain;
1191  p->name=AcquirePolicyString(name,1);
1193  }
1194  p->value=AcquirePolicyString(value,1);
1196  if (status == MagickFalse)
1198  return(status);
1199 }
1200 
1202  const PolicyDomain domain,const char *name,const char *value,
1203  ExceptionInfo *exception)
1204 {
1205  char
1206  *current_value;
1207 
1208  magick_unreferenced(exception);
1209  assert(exception != (ExceptionInfo *) NULL);
1210  if ((name == (const char *) NULL) || (value == (const char *) NULL))
1211  return(MagickFalse);
1212  switch(domain)
1213  {
1214  case CachePolicyDomain:
1215  {
1216  if (LocaleCompare(name,"memory-map") == 0)
1217  {
1218  if (LocaleCompare(value,"anonymous") != 0)
1219  return(MagickFalse);
1222  return(SetPolicyValue(domain,name,value));
1223  }
1224  if (LocaleCompare(name,"synchronize") == 0)
1225  return(SetPolicyValue(domain,name,value));
1226  break;
1227  }
1228  case ResourcePolicyDomain:
1229  {
1230  ssize_t
1231  type;
1232 
1233  if (LocaleCompare(name,"temporary-path") == 0)
1234  return(SetPolicyValue(domain,name,value));
1236  if (type >= 0)
1237  {
1239  limit;
1240 
1241  limit=MagickResourceInfinity;
1242  if (LocaleCompare("unlimited",value) != 0)
1243  limit=StringToMagickSizeType(value,100.0);
1244  return(SetMagickResourceLimit((ResourceType) type,limit));
1245  }
1246  break;
1247  }
1248  case SystemPolicyDomain:
1249  {
1250  if (LocaleCompare(name,"font") == 0)
1251  return(SetPolicyValue(domain,name,value));
1252  if (LocaleCompare(name,"max-memory-request") == 0)
1253  {
1254  current_value=GetPolicyValue("system:max-memory-request");
1255  if ((current_value == (char *) NULL) ||
1256  (StringToSizeType(value,100.0) < StringToSizeType(current_value,100.0)))
1257  {
1258  if (current_value != (char *) NULL)
1259  current_value=DestroyString(current_value);
1261  return(SetPolicyValue(domain,name,value));
1262  }
1263  if (current_value != (char *) NULL)
1264  current_value=DestroyString(current_value);
1265  }
1266  if (LocaleCompare(name,"memory-map") == 0)
1267  {
1268  if (LocaleCompare(value,"anonymous") != 0)
1269  return(MagickFalse);
1271  return(SetPolicyValue(domain,name,value));
1272  }
1273  if (LocaleCompare(name,"precision") == 0)
1274  {
1276  return(SetPolicyValue(domain,name,value));
1277  }
1278  if (LocaleCompare(name,"shred") == 0)
1279  {
1280  current_value=GetPolicyValue("system:shred");
1281  if ((current_value == (char *) NULL) ||
1282  (StringToInteger(value) > StringToInteger(current_value)))
1283  {
1284  if (current_value != (char *) NULL)
1285  current_value=DestroyString(current_value);
1286  return(SetPolicyValue(domain,name,value));
1287  }
1288  if (current_value != (char *) NULL)
1289  current_value=DestroyString(current_value);
1290  }
1291  break;
1292  }
1293  case CoderPolicyDomain:
1294  case DelegatePolicyDomain:
1295  case FilterPolicyDomain:
1296  case ModulePolicyDomain:
1297  case PathPolicyDomain:
1298  default:
1299  break;
1300  }
1301  return(MagickFalse);
1302 }
MagickBooleanType stealth
Definition: policy.c:95
char * value
Definition: policy.c:90
MagickPrivate MagickBooleanType ResourceComponentGenesis(void)
Definition: resource.c:1143
#define MagickMaxRecursionDepth
Definition: studio.h:352
static size_t StringToSizeType(const char *string, const double interval)
MagickExport const PolicyInfo ** GetPolicyInfoList(const char *pattern, size_t *number_policies, ExceptionInfo *exception)
Definition: policy.c:368
MagickExport MagickBooleanType IsRightsAuthorized(const PolicyDomain domain, const PolicyRights rights, const char *pattern)
Definition: policy.c:620
MagickExport size_t ConcatenateMagickString(char *magick_restrict destination, const char *magick_restrict source, const size_t length)
Definition: string.c:392
MagickExport MagickBooleanType ListPolicyInfo(FILE *file, ExceptionInfo *exception)
Definition: policy.c:694
MagickExport void UnlockSemaphoreInfo(SemaphoreInfo *semaphore_info)
Definition: semaphore.c:449
MagickExport void ResetLinkedListIterator(LinkedListInfo *list_info)
Definition: linked-list.c:959
MagickExport ssize_t ParseCommandOption(const CommandOption option, const MagickBooleanType list, const char *options)
Definition: option.c:3052
static SemaphoreInfo * policy_semaphore
Definition: policy.c:134
SemaphoreInfo * semaphore
Definition: policy.c:100
PolicyRights
Definition: policy.h:41
#define ThrowFatalException(severity, tag)
static int StringToInteger(const char *magick_restrict value)
MagickExport LinkedListInfo * DestroyLinkedList(LinkedListInfo *list_info, void *(*relinquish_value)(void *))
Definition: linked-list.c:219
struct _PolicyMapInfo PolicyMapInfo
char * name
Definition: policy.c:90
MagickBooleanType debug
Definition: policy.c:95
MagickExport SemaphoreInfo * AcquireSemaphoreInfo(void)
Definition: semaphore.c:192
MagickExport MagickBooleanType InsertValueInLinkedList(LinkedListInfo *list_info, const size_t index, const void *value)
Definition: linked-list.c:447
const char * name
Definition: policy.c:115
char * pattern
Definition: policy.c:90
MagickExport MagickBooleanType SetMagickResourceLimit(const ResourceType type, const MagickSizeType limit)
Definition: resource.c:1352
static PolicyInfo * GetPolicyInfo(const char *name, ExceptionInfo *exception)
Definition: policy.c:272
MagickExport ExceptionInfo * AcquireExceptionInfo(void)
Definition: exception.c:115
MagickExport MagickBooleanType AppendValueToLinkedList(LinkedListInfo *list_info, const void *value)
Definition: linked-list.c:111
MagickExport size_t CopyMagickString(char *magick_restrict destination, const char *magick_restrict source, const size_t length)
Definition: string.c:719
MagickExport void * RemoveElementByValueFromLinkedList(LinkedListInfo *list_info, const void *value)
Definition: linked-list.c:756
static LinkedListInfo * policy_cache
Definition: policy.c:131
MagickPrivate MagickBooleanType PolicyComponentGenesis(void)
Definition: policy.c:1013
MagickExport MagickBooleanType SetMagickSecurityPolicyValue(const PolicyDomain domain, const char *name, const char *value, ExceptionInfo *exception)
Definition: policy.c:1201
Definition: log.h:52
static const PolicyMapInfo PolicyMap[]
Definition: policy.c:124
MagickExport void * GetNextValueInLinkedList(LinkedListInfo *list_info)
Definition: linked-list.c:305
size_t signature
Definition: policy.c:103
#define MagickCoreSignature
MagickExport void LockSemaphoreInfo(SemaphoreInfo *semaphore_info)
Definition: semaphore.c:293
MagickExport unsigned char * GetStringInfoDatum(const StringInfo *string_info)
Definition: string.c:1168
MagickExport LinkedListInfo * GetConfigureOptions(const char *filename, ExceptionInfo *exception)
Definition: configure.c:642
static MagickBooleanType LoadPolicyCache(LinkedListInfo *, const char *, const char *, const size_t, ExceptionInfo *)
Definition: policy.c:793
MagickExport void GetPathComponent(const char *path, PathType type, char *component)
Definition: utility.c:1221
MagickExport ssize_t FormatLocaleFile(FILE *file, const char *magick_restrict format,...)
Definition: locale.c:372
MagickBooleanType
Definition: magick-type.h:169
#define DirectorySeparator
Definition: studio.h:267
unsigned int MagickStatusType
Definition: magick-type.h:125
MagickPrivate void ResetMagickPrecision(void)
Definition: magick.c:1718
MagickExport MagickBooleanType GlobExpression(const char *magick_restrict expression, const char *magick_restrict pattern, const MagickBooleanType case_insensitive)
Definition: token.c:355
MagickExport const char * CommandOptionToMnemonic(const CommandOption option, const ssize_t type)
Definition: option.c:2761
MagickExport void * AcquireCriticalMemory(const size_t size)
Definition: memory.c:626
MagickExport void * AcquireQuantumMemory(const size_t count, const size_t quantum)
Definition: memory.c:665
MagickExport int LocaleNCompare(const char *p, const char *q, const size_t length)
Definition: locale.c:1527
MagickExport magick_hot_spot size_t GetNextToken(const char *magick_restrict start, const char **magick_restrict end, const size_t extent, char *magick_restrict token)
Definition: token.c:174
size_t MagickSizeType
Definition: magick-type.h:134
#define MagickPathExtent
MagickExport MagickBooleanType IsStringTrue(const char *value)
Definition: string.c:1378
MagickExport MagickBooleanType IsEventLogging(void)
Definition: log.c:725
static MagickBooleanType SetPolicyValue(const PolicyDomain domain, const char *name, const char *value)
Definition: policy.c:1160
PolicyRights rights
Definition: policy.c:87
MagickExport char ** GetPolicyList(const char *pattern, size_t *number_policies, ExceptionInfo *exception)
Definition: policy.c:464
MagickPrivate void ResetCacheAnonymousMemory(void)
MagickExport MagickBooleanType ThrowMagickException(ExceptionInfo *exception, const char *module, const char *function, const size_t line, const ExceptionType severity, const char *tag, const char *format,...)
Definition: exception.c:1145
MagickExport MagickBooleanType LogMagickEvent(const LogEventType type, const char *module, const char *function, const size_t line, const char *format,...)
Definition: log.c:1660
MagickExport LinkedListInfo * NewLinkedList(const size_t capacity)
Definition: linked-list.c:713
MagickPrivate void ResetStreamAnonymousMemory(void)
PolicyDomain
Definition: policy.h:28
ResourceType
Definition: resource_.h:25
MagickExport int LocaleCompare(const char *p, const char *q)
Definition: locale.c:1403
#define GetMagickModule()
Definition: log.h:28
MagickExport const char * GetStringInfoPath(const StringInfo *string_info)
Definition: string.c:1255
MagickBooleanType exempt
Definition: policy.c:95
#define PolicyFilename
Definition: policy.c:73
#define MagickResourceInfinity
Definition: resource_.h:41
MagickExport MagickBooleanType SetMagickSecurityPolicy(const char *policy, ExceptionInfo *exception)
Definition: policy.c:1097
MagickExport char * DestroyString(char *string)
Definition: string.c:776
MagickExport void * AcquireMagickMemory(const size_t size)
Definition: memory.c:552
MagickExport void ActivateSemaphoreInfo(SemaphoreInfo **semaphore_info)
Definition: semaphore.c:98
const char * pattern
Definition: policy.c:115
MagickExport size_t GetNumberOfElementsInLinkedList(const LinkedListInfo *list_info)
Definition: linked-list.c:348
static MagickSizeType StringToMagickSizeType(const char *string, const double interval)
static LinkedListInfo * AcquirePolicyCache(const char *filename, ExceptionInfo *exception)
Definition: policy.c:170
MagickExport char * GetPolicyValue(const char *name)
Definition: policy.c:531
const PolicyDomain domain
Definition: policy.c:109
PolicyDomain domain
Definition: policy.c:84
MagickExport void * RelinquishMagickMemory(void *memory)
Definition: memory.c:1162
#define magick_unreferenced(x)
const PolicyRights rights
Definition: policy.c:112
#define MagickPrivate
MagickPrivate char * FileToXML(const char *, const size_t)
Definition: xml-tree.c:524
#define MagickExport
MagickPrivate void PolicyComponentTerminus(void)
Definition: policy.c:1060
const char * value
Definition: policy.c:115
static char * AcquirePolicyString(const char *source, const size_t pad)
Definition: policy.c:441
static void * DestroyPolicyElement(void *policy_info)
Definition: policy.c:1039
MagickPrivate void ResetMaxMemoryRequest(void)
char * path
Definition: policy.c:81
MagickExport void RelinquishSemaphoreInfo(SemaphoreInfo **semaphore_info)
Definition: semaphore.c:351
MagickExport LinkedListInfo * DestroyConfigureOptions(LinkedListInfo *options)
Definition: configure.c:314
MagickPrivate void ResetVirtualAnonymousMemory(void)
Definition: memory.c:1345
MagickExport ExceptionInfo * DestroyExceptionInfo(ExceptionInfo *exception)
Definition: exception.c:418
static MagickBooleanType IsPolicyCacheInstantiated(ExceptionInfo *)
Definition: policy.c:578