acltools.cpp 83 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494
  1. /** BEGIN COPYRIGHT BLOCK
  2. * This Program is free software; you can redistribute it and/or modify it under
  3. * the terms of the GNU General Public License as published by the Free Software
  4. * Foundation; version 2 of the License.
  5. *
  6. * This Program is distributed in the hope that it will be useful, but WITHOUT
  7. * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  8. * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
  9. *
  10. * You should have received a copy of the GNU General Public License along with
  11. * this Program; if not, write to the Free Software Foundation, Inc., 59 Temple
  12. * Place, Suite 330, Boston, MA 02111-1307 USA.
  13. *
  14. * In addition, as a special exception, Red Hat, Inc. gives You the additional
  15. * right to link the code of this Program with code not covered under the GNU
  16. * General Public License ("Non-GPL Code") and to distribute linked combinations
  17. * including the two, subject to the limitations in this paragraph. Non-GPL Code
  18. * permitted under this exception must only link to the code of this Program
  19. * through those well defined interfaces identified in the file named EXCEPTION
  20. * found in the source code files (the "Approved Interfaces"). The files of
  21. * Non-GPL Code may instantiate templates or use macros or inline functions from
  22. * the Approved Interfaces without causing the resulting work to be covered by
  23. * the GNU General Public License. Only Red Hat, Inc. may make changes or
  24. * additions to the list of Approved Interfaces. You must obey the GNU General
  25. * Public License in all respects for all of the Program code and other code used
  26. * in conjunction with the Program except the Non-GPL Code covered by this
  27. * exception. If you modify this file, you may extend this exception to your
  28. * version of the file, but you are not obligated to do so. If you do not wish to
  29. * provide this exception without modification, you must delete this exception
  30. * statement from your version and license this file solely under the GPL without
  31. * exception.
  32. *
  33. *
  34. * Copyright (C) 2001 Sun Microsystems, Inc. Used by permission.
  35. * Copyright (C) 2005 Red Hat, Inc.
  36. * All rights reserved.
  37. * END COPYRIGHT BLOCK **/
  38. #ifdef HAVE_CONFIG_H
  39. # include <config.h>
  40. #endif
  41. /*
  42. * Tools to build and maintain access control lists.
  43. */
  44. #include <stdio.h>
  45. #include <string.h>
  46. #define ALLOCATE_ATTR_TABLE 1 /* Include the table of PList names */
  47. #include <netsite.h>
  48. #include <base/plist.h>
  49. #include <base/util.h>
  50. #include <base/crit.h>
  51. #include <base/file.h>
  52. #include <libaccess/acl.h>
  53. #include "aclpriv.h"
  54. #include <libaccess/aclproto.h>
  55. #include <libaccess/aclerror.h>
  56. #include <libaccess/symbols.h>
  57. #include <libaccess/aclstruct.h>
  58. #include <libaccess/las.h>
  59. #include "aclscan.h"
  60. #include "parse.h"
  61. #include "oneeval.h"
  62. #include <libaccess/authdb.h>
  63. static CRITICAL acl_parse_crit = NULL;
  64. /*
  65. * Allocate a new ACL handle
  66. *
  67. * This function creates a new ACL structure that will be used for
  68. * access control information.
  69. *
  70. * Input:
  71. * tag Specifies an identifier name for the new ACL, or
  72. * it may be NULL when no name is required.
  73. * Returns:
  74. * A new ACL structure.
  75. */
  76. NSAPI_PUBLIC ACLHandle_t *
  77. ACL_AclNew(NSErr_t *errp, char *tag )
  78. {
  79. ACLHandle_t *handle;
  80. handle = ( ACLHandle_t * ) PERM_CALLOC ( 1 * sizeof (ACLHandle_t) );
  81. if ( handle && tag ) {
  82. handle->tag = PERM_STRDUP( tag );
  83. if ( handle->tag == NULL ) {
  84. PERM_FREE(handle);
  85. return(NULL);
  86. }
  87. }
  88. return(handle);
  89. }
  90. /*
  91. * Appends to a specified ACL
  92. *
  93. * This function appends a specified ACL to the end of a given ACL list.
  94. *
  95. * Input:
  96. * errp The error stack
  97. * flags should always be zero now
  98. * acl_list target ACL list
  99. * acl new acl
  100. * Returns:
  101. * < 0 failure
  102. * > 0 The number of acl's in the current list
  103. */
  104. NSAPI_PUBLIC int
  105. ACL_ExprAppend( NSErr_t *errp, ACLHandle_t *acl,
  106. ACLExprHandle_t *expr )
  107. {
  108. if ( acl == NULL || expr == NULL )
  109. return(ACLERRUNDEF);
  110. expr->acl_tag = acl->tag;
  111. if ( expr->expr_type == ACL_EXPR_TYPE_AUTH ||
  112. expr->expr_type == ACL_EXPR_TYPE_RESPONSE ) {
  113. expr->expr_number = -1; // expr number isn't valid
  114. } else {
  115. acl->expr_count++;
  116. expr->expr_number = acl->expr_count;
  117. }
  118. if ( acl->expr_list_head == NULL ) {
  119. acl->expr_list_head = expr;
  120. acl->expr_list_tail = expr;
  121. } else {
  122. acl->expr_list_tail->expr_next = expr;
  123. acl->expr_list_tail = expr;
  124. }
  125. return(acl->expr_count);
  126. }
  127. /*
  128. * Add authentication information to an ACL
  129. *
  130. * This function adds authentication data to an expr, based on
  131. * the information provided by the parameters.
  132. *
  133. * Input:
  134. * expr an authenticate expression to add database
  135. * and method information to. ie, auth_info
  136. * auth_info authentication information, eg database,
  137. * method, etc.
  138. * Returns:
  139. * 0 success
  140. * < 0 failure
  141. */
  142. NSAPI_PUBLIC int
  143. ACL_ExprAddAuthInfo( ACLExprHandle_t *expr, PList_t auth_info )
  144. {
  145. if ( expr == NULL || auth_info == NULL )
  146. return(ACLERRUNDEF);
  147. expr->expr_auth = auth_info;
  148. return(0);
  149. }
  150. /*
  151. * Add authorization information to an ACL
  152. *
  153. * This function adds an authorization to a given ACL, based on the information
  154. * provided by the parameters.
  155. *
  156. * Input:
  157. * errp The error stack
  158. * access_rights strings which identify the access rights to be
  159. * controlled by the generated expr.
  160. * flags processing flags
  161. * allow non-zero to allow the indicated rights, or zero to
  162. * deny them.
  163. * attr_expr handle for an attribute expression, which may be
  164. * obtained by calling ACL_ExprNew()
  165. * Returns:
  166. * 0 success
  167. * < 0 failure
  168. */
  169. NSAPI_PUBLIC int
  170. ACL_AddPermInfo( NSErr_t *errp, ACLHandle_t *acl,
  171. char **access_rights,
  172. PFlags_t flags,
  173. int allow,
  174. ACLExprHandle_t *expr,
  175. char *tag )
  176. {
  177. if ( acl == NULL || expr == NULL )
  178. return(ACLERRUNDEF);
  179. expr->expr_flags = flags;
  180. expr->expr_argv = (char **) access_rights;
  181. expr->expr_tag = PERM_STRDUP( tag );
  182. if ( expr->expr_tag == NULL )
  183. return(ACLERRNOMEM);
  184. return(ACL_ExprAppend( errp, acl, expr ));
  185. }
  186. /*
  187. * Add rights information to an expression
  188. *
  189. * This function adds a right to an authorization, based on the information
  190. * provided by the parameters.
  191. *
  192. * Input:
  193. * errp The error stack
  194. * access_right strings which identify the access rights to be
  195. * controlled by the generated expr.
  196. * expr handle for an attribute expression, which may be
  197. * obtained by calling ACL_ExprNew()
  198. * Returns:
  199. * 0 success
  200. * < 0 failure
  201. */
  202. NSAPI_PUBLIC int
  203. ACL_ExprAddArg( NSErr_t *errp,
  204. ACLExprHandle_t *expr,
  205. char *arg )
  206. {
  207. if ( expr == NULL )
  208. return(ACLERRUNDEF);
  209. if (expr->expr_argv == NULL)
  210. expr->expr_argv = (char **) PERM_MALLOC( 2 * sizeof(char *) );
  211. else
  212. expr->expr_argv = (char **) PERM_REALLOC( expr->expr_argv,
  213. (expr->expr_argc+2)
  214. * sizeof(char *) );
  215. if (expr->expr_argv == NULL)
  216. return(ACLERRNOMEM);
  217. expr->expr_argv[expr->expr_argc] = PERM_STRDUP( arg );
  218. if (expr->expr_argv[expr->expr_argc] == NULL)
  219. return(ACLERRNOMEM);
  220. expr->expr_argc++;
  221. expr->expr_argv[expr->expr_argc] = NULL;
  222. return(0);
  223. }
  224. NSAPI_PUBLIC int
  225. ACL_ExprSetDenyWith( NSErr_t *errp, ACLExprHandle_t *expr, char *deny_type, char *deny_response)
  226. {
  227. int rv;
  228. if ( expr->expr_argc == 0 ) {
  229. if ( (rv = ACL_ExprAddArg(errp, expr, deny_type)) < 0 )
  230. return(rv);
  231. if ( (rv = ACL_ExprAddArg(errp, expr, deny_response)) < 0 )
  232. return(rv);
  233. } else if ( expr->expr_argc == 2 ) {
  234. if ( deny_type ) {
  235. if ( expr->expr_argv[0] )
  236. PERM_FREE(expr->expr_argv[0]);
  237. expr->expr_argv[0] = PERM_STRDUP(deny_type);
  238. if ( expr->expr_argv[0] == NULL )
  239. return(ACLERRNOMEM);
  240. }
  241. if ( deny_response ) {
  242. if ( expr->expr_argv[1] )
  243. PERM_FREE(expr->expr_argv[1]);
  244. expr->expr_argv[1] = PERM_STRDUP(deny_response);
  245. if ( expr->expr_argv[0] == NULL )
  246. return(ACLERRNOMEM);
  247. }
  248. } else {
  249. return(ACLERRINTERNAL);
  250. }
  251. return(0);
  252. }
  253. NSAPI_PUBLIC int
  254. ACL_ExprGetDenyWith( NSErr_t *errp, ACLExprHandle_t *expr, char **deny_type,
  255. char **deny_response)
  256. {
  257. if ( expr->expr_argc == 2 ) {
  258. *deny_type = expr->expr_argv[0];
  259. *deny_response = expr->expr_argv[1];
  260. return(0);
  261. } else {
  262. return(ACLERRUNDEF);
  263. }
  264. }
  265. /*
  266. * Function to set the authorization statement processing flags.
  267. *
  268. * Input:
  269. * errp The error reporting stack
  270. * expr The authoization statement
  271. * flags The flags to set
  272. * Returns:
  273. * 0 success
  274. * < 0 failure
  275. */
  276. NSAPI_PUBLIC int
  277. ACL_ExprSetPFlags( NSErr_t *errp,
  278. ACLExprHandle_t *expr,
  279. PFlags_t flags )
  280. {
  281. if ( expr == NULL )
  282. return(ACLERRUNDEF);
  283. expr->expr_flags |= flags;
  284. return(0);
  285. }
  286. /*
  287. * Function to clear the authorization statement processing flags.
  288. *
  289. * Input:
  290. * errp The error reporting stack
  291. * expr The authoization statement
  292. * Returns:
  293. * 0 success
  294. * < 0 failure
  295. */
  296. NSAPI_PUBLIC int
  297. ACL_ExprClearPFlags( NSErr_t *errp,
  298. ACLExprHandle_t *expr )
  299. {
  300. if ( expr == NULL )
  301. return(ACLERRUNDEF);
  302. expr->expr_flags = 0;
  303. return(0);
  304. }
  305. /*
  306. * Allocate a new expression handle.
  307. *
  308. * Returns:
  309. * NULL If handle could not be allocated.
  310. * pointer New handle.
  311. */
  312. NSAPI_PUBLIC ACLExprHandle_t *
  313. ACL_ExprNew( const ACLExprType_t expr_type )
  314. {
  315. ACLExprHandle_t *expr_handle;
  316. expr_handle = ( ACLExprHandle_t * ) PERM_CALLOC ( sizeof(ACLExprHandle_t) );
  317. if ( expr_handle ) {
  318. expr_handle->expr_arry = ( ACLExprEntry_t * )
  319. PERM_CALLOC( ACL_TERM_BSIZE * sizeof(ACLExprEntry_t) ) ;
  320. expr_handle->expr_arry_size = ACL_TERM_BSIZE;
  321. expr_handle->expr_type = expr_type;
  322. expr_handle->expr_raw = ( ACLExprRaw_t * )
  323. PERM_CALLOC( ACL_TERM_BSIZE * sizeof(ACLExprRaw_t) ) ;
  324. expr_handle->expr_raw_size = ACL_TERM_BSIZE;
  325. }
  326. return(expr_handle);
  327. }
  328. /*
  329. * LOCAL FUNCTION
  330. *
  331. * displays the ASCII equivalent index value.
  332. */
  333. static char *
  334. acl_index_string ( int value, char *buffer )
  335. {
  336. if ( value == ACL_TRUE_IDX ) {
  337. strcpy( buffer, "TRUE" );
  338. return( buffer );
  339. }
  340. if ( value == ACL_FALSE_IDX ) {
  341. strcpy( buffer, "FALSE" );
  342. return( buffer );
  343. }
  344. sprintf( buffer, "goto %d", value );
  345. return( buffer );
  346. }
  347. /*
  348. * LOCAL FUNCTION
  349. *
  350. * displays ASCII equivalent of CmpOp_t
  351. */
  352. static char *
  353. acl_comp_string( CmpOp_t cmp )
  354. {
  355. switch (cmp) {
  356. case CMP_OP_EQ:
  357. return("=");
  358. case CMP_OP_NE:
  359. return("!=");
  360. case CMP_OP_GT:
  361. return(">");
  362. case CMP_OP_LT:
  363. return("<");
  364. case CMP_OP_GE:
  365. return(">=");
  366. case CMP_OP_LE:
  367. return("<=");
  368. default:
  369. return("unknown op");
  370. }
  371. }
  372. /*
  373. * Add a term to the specified attribute expression.
  374. *
  375. * Input:
  376. * errp Error stack
  377. * acl_expr Target expression handle
  378. * attr_name Term Attribute name
  379. * cmp Comparison operator
  380. * attr_pattern Pattern for comparison
  381. * Ouput:
  382. * acl_expr New term added
  383. * Returns:
  384. * 0 Success
  385. * < 0 Error
  386. */
  387. NSAPI_PUBLIC int
  388. ACL_ExprTerm( NSErr_t *errp, ACLExprHandle_t *acl_expr,
  389. char *attr_name,
  390. CmpOp_t cmp,
  391. char *attr_pattern )
  392. {
  393. ACLExprEntry_t *expr;
  394. ACLExprRaw_t *raw_expr;
  395. if ( acl_expr == NULL || acl_expr->expr_arry == NULL )
  396. return(ACLERRUNDEF);
  397. if ( acl_expr->expr_term_index >= acl_expr->expr_arry_size ) {
  398. acl_expr->expr_arry = ( ACLExprEntry_t *)
  399. PERM_REALLOC ( acl_expr->expr_arry,
  400. (acl_expr->expr_arry_size + ACL_TERM_BSIZE)
  401. * sizeof(ACLExprEntry_t));
  402. if ( acl_expr->expr_arry == NULL )
  403. return(ACLERRNOMEM);
  404. acl_expr->expr_arry_size += ACL_TERM_BSIZE;
  405. }
  406. expr = &acl_expr->expr_arry[acl_expr->expr_term_index];
  407. acl_expr->expr_term_index++;
  408. expr->attr_name = PERM_STRDUP(attr_name);
  409. if ( expr->attr_name == NULL )
  410. return(ACLERRNOMEM);
  411. expr->comparator = cmp;
  412. expr->attr_pattern = PERM_STRDUP(attr_pattern);
  413. if ( expr->attr_pattern == NULL )
  414. return(ACLERRNOMEM);
  415. expr->true_idx = ACL_TRUE_IDX;
  416. expr->false_idx = ACL_FALSE_IDX;
  417. expr->start_flag = 1;
  418. expr->las_cookie = 0;
  419. expr->las_eval_func = 0;
  420. if ( acl_expr->expr_raw_index >= acl_expr->expr_raw_size ) {
  421. acl_expr->expr_raw = ( ACLExprRaw_t *)
  422. PERM_REALLOC ( acl_expr->expr_raw,
  423. (acl_expr->expr_raw_size + ACL_TERM_BSIZE)
  424. * sizeof(ACLExprRaw_t));
  425. if ( acl_expr->expr_raw == NULL )
  426. return(ACLERRNOMEM);
  427. acl_expr->expr_raw_size += ACL_TERM_BSIZE;
  428. }
  429. raw_expr = &acl_expr->expr_raw[acl_expr->expr_raw_index];
  430. acl_expr->expr_raw_index++;
  431. raw_expr->attr_name = expr->attr_name;
  432. raw_expr->comparator = cmp;
  433. raw_expr->attr_pattern = expr->attr_pattern;
  434. raw_expr->logical = (ACLExprOp_t)0;
  435. #ifdef DEBUG_LEVEL_2
  436. printf ( "%d: %s %s %s, t=%d, f=%d\n",
  437. acl_expr->expr_term_index - 1,
  438. expr->attr_name,
  439. acl_comp_string( expr->comparator ),
  440. expr->attr_pattern,
  441. expr->true_idx,
  442. expr->false_idx );
  443. #endif
  444. return(0);
  445. }
  446. /*
  447. * Negate the previous term or subexpression.
  448. *
  449. * Input:
  450. * errp The error stack
  451. * acl_expr The expression to negate
  452. * Ouput
  453. * acl_expr The negated expression
  454. * Returns:
  455. * 0 Success
  456. * < 0 Failure
  457. */
  458. NSAPI_PUBLIC int
  459. ACL_ExprNot( NSErr_t *errp, ACLExprHandle_t *acl_expr )
  460. {
  461. int idx;
  462. int ii;
  463. int expr_one = 0;
  464. ACLExprRaw_t *raw_expr;
  465. if ( acl_expr == NULL )
  466. return(ACLERRUNDEF);
  467. if ( acl_expr->expr_raw_index >= acl_expr->expr_raw_size ) {
  468. acl_expr->expr_raw = ( ACLExprRaw_t *)
  469. PERM_REALLOC ( acl_expr->expr_raw,
  470. (acl_expr->expr_raw_size + ACL_TERM_BSIZE)
  471. * sizeof(ACLExprRaw_t));
  472. if ( acl_expr->expr_raw == NULL )
  473. return(ACLERRNOMEM);
  474. acl_expr->expr_raw_size += ACL_TERM_BSIZE;
  475. }
  476. raw_expr = &acl_expr->expr_raw[acl_expr->expr_raw_index];
  477. acl_expr->expr_raw_index++;
  478. raw_expr->logical = ACL_EXPR_OP_NOT;
  479. raw_expr->attr_name = NULL;
  480. /* Find the last expression */
  481. idx = acl_expr->expr_term_index - 1;
  482. for ( ii = idx; ii >= 0; ii-- ) {
  483. if ( acl_expr->expr_arry[ii].start_flag ) {
  484. expr_one = ii;
  485. break;
  486. }
  487. }
  488. #ifdef DEBUG_LEVEL_2
  489. printf("not, start index=%d\n", expr_one);
  490. #endif
  491. /*
  492. * The intent here is negate the last expression by
  493. * modifying the true and false links.
  494. */
  495. for ( ii = expr_one; ii < acl_expr->expr_term_index; ii++ ) {
  496. if ( acl_expr->expr_arry[ii].true_idx == ACL_TRUE_IDX )
  497. acl_expr->expr_arry[ii].true_idx = ACL_FALSE_IDX;
  498. else if ( acl_expr->expr_arry[ii].true_idx == ACL_FALSE_IDX )
  499. acl_expr->expr_arry[ii].true_idx = ACL_TRUE_IDX;
  500. if ( acl_expr->expr_arry[ii].false_idx == ACL_TRUE_IDX )
  501. acl_expr->expr_arry[ii].false_idx = ACL_FALSE_IDX;
  502. else if ( acl_expr->expr_arry[ii].false_idx == ACL_FALSE_IDX )
  503. acl_expr->expr_arry[ii].false_idx = ACL_TRUE_IDX;
  504. }
  505. return(0) ;
  506. }
  507. /*
  508. * Logical 'and' the previous two terms or subexpressions.
  509. *
  510. * Input:
  511. * errp The error stack
  512. * acl_expr The terms or subexpressions
  513. * Output:
  514. * acl_expr The expression after logical 'and'
  515. */
  516. NSAPI_PUBLIC int
  517. ACL_ExprAnd( NSErr_t *errp, ACLExprHandle_t *acl_expr )
  518. {
  519. int idx;
  520. int ii;
  521. int expr_one = ACL_FALSE_IDX;
  522. int expr_two = ACL_FALSE_IDX;
  523. ACLExprRaw_t *raw_expr;
  524. if ( acl_expr == NULL )
  525. return(ACLERRUNDEF);
  526. if ( acl_expr->expr_raw_index >= acl_expr->expr_raw_size ) {
  527. acl_expr->expr_raw = ( ACLExprRaw_t *)
  528. PERM_REALLOC ( acl_expr->expr_raw,
  529. (acl_expr->expr_raw_size + ACL_TERM_BSIZE)
  530. * sizeof(ACLExprRaw_t) );
  531. if ( acl_expr->expr_raw == NULL )
  532. return(ACLERRNOMEM);
  533. acl_expr->expr_raw_size += ACL_TERM_BSIZE;
  534. }
  535. raw_expr = &acl_expr->expr_raw[acl_expr->expr_raw_index];
  536. acl_expr->expr_raw_index++;
  537. raw_expr->logical = ACL_EXPR_OP_AND;
  538. raw_expr->attr_name = NULL;
  539. /* Find the last two expressions */
  540. idx = acl_expr->expr_term_index - 1;
  541. for ( ii = idx; ii >= 0; ii-- ) {
  542. if ( acl_expr->expr_arry[ii].start_flag ) {
  543. if ( expr_two == ACL_FALSE_IDX )
  544. expr_two = ii;
  545. else if ( expr_one == ACL_FALSE_IDX ) {
  546. expr_one = ii;
  547. break;
  548. }
  549. }
  550. }
  551. #ifdef DEBUG_LEVEL_2
  552. printf("and, index=%d, first expr=%d, second expr=%d\n", idx, expr_one, expr_two);
  553. #endif
  554. for ( ii = expr_one; ii < expr_two; ii++) {
  555. if ( acl_expr->expr_arry[ii].true_idx == ACL_TRUE_IDX )
  556. acl_expr->expr_arry[ii].true_idx = expr_two;
  557. if ( acl_expr->expr_arry[ii].false_idx == ACL_TRUE_IDX )
  558. acl_expr->expr_arry[ii].false_idx = expr_two;
  559. }
  560. acl_expr->expr_arry[expr_two].start_flag = 0;
  561. return(0);
  562. }
  563. /*
  564. * Logical 'or' the previous two terms or subexpressions.
  565. *
  566. * Input:
  567. * errp The error stack
  568. * acl_expr The terms or subexpressions
  569. * Output:
  570. * acl_expr The expression after logical 'or'
  571. */
  572. NSAPI_PUBLIC int
  573. ACL_ExprOr( NSErr_t *errp, ACLExprHandle_t *acl_expr )
  574. {
  575. int idx;
  576. int ii;
  577. int expr_one = ACL_FALSE_IDX;
  578. int expr_two = ACL_FALSE_IDX;
  579. ACLExprRaw_t *raw_expr;
  580. if ( acl_expr == NULL )
  581. return(ACLERRUNDEF);
  582. if ( acl_expr->expr_raw_index >= acl_expr->expr_raw_size ) {
  583. acl_expr->expr_raw = ( ACLExprRaw_t *)
  584. PERM_REALLOC ( acl_expr->expr_raw,
  585. (acl_expr->expr_raw_size + ACL_TERM_BSIZE)
  586. * sizeof(ACLExprRaw_t) );
  587. if ( acl_expr->expr_raw == NULL )
  588. return(ACLERRNOMEM);
  589. acl_expr->expr_raw_size += ACL_TERM_BSIZE;
  590. }
  591. raw_expr = &acl_expr->expr_raw[acl_expr->expr_raw_index];
  592. acl_expr->expr_raw_index++;
  593. raw_expr->logical = ACL_EXPR_OP_OR;
  594. raw_expr->attr_name = NULL;
  595. /* Find the last two expressions */
  596. idx = acl_expr->expr_term_index - 1;
  597. for ( ii = idx; ii >= 0; ii-- ) {
  598. if ( acl_expr->expr_arry[ii].start_flag ) {
  599. if ( expr_two == ACL_FALSE_IDX )
  600. expr_two = ii;
  601. else if ( expr_one == ACL_FALSE_IDX ) {
  602. expr_one = ii;
  603. break;
  604. }
  605. }
  606. }
  607. #ifdef DEBUG_LEVEL_2
  608. printf("or, index=%d, first expr=%d, second expr=%d\n", idx, expr_one, expr_two);
  609. #endif
  610. for ( ii = expr_one; ii < expr_two; ii++) {
  611. if ( acl_expr->expr_arry[ii].true_idx == ACL_FALSE_IDX )
  612. acl_expr->expr_arry[ii].true_idx = expr_two;
  613. if ( acl_expr->expr_arry[ii].false_idx == ACL_FALSE_IDX )
  614. acl_expr->expr_arry[ii].false_idx = expr_two;
  615. }
  616. acl_expr->expr_arry[expr_two].start_flag = 0;
  617. return(0);
  618. }
  619. /*
  620. * INTERNAL FUNCTION (GLOBAL)
  621. *
  622. * Write an expression array to standard output. This
  623. * is only useful debugging.
  624. */
  625. int
  626. ACL_ExprDisplay( ACLExprHandle_t *acl_expr )
  627. {
  628. int ii;
  629. char buffer[256];
  630. if ( acl_expr == NULL )
  631. return(0);
  632. for ( ii = 0; ii < acl_expr->expr_term_index; ii++ ) {
  633. printf ("%d: if ( %s %s %s ) ",
  634. ii,
  635. acl_expr->expr_arry[ii].attr_name,
  636. acl_comp_string( acl_expr->expr_arry[ii].comparator ),
  637. acl_expr->expr_arry[ii].attr_pattern );
  638. printf("%s ", acl_index_string(acl_expr->expr_arry[ii].true_idx, buffer));
  639. printf("else %s\n",
  640. acl_index_string(acl_expr->expr_arry[ii].false_idx, buffer) );
  641. }
  642. return(0);
  643. }
  644. /*
  645. * Creates a handle for a new list of ACLs
  646. *
  647. * This function creates a new list of ACLs. The list is initially empty
  648. * and can be added to by ACL_ListAppend(). A resource manager would use
  649. * these functions to build up a list of all the ACLs applicable to a
  650. * particular resource access.
  651. *
  652. * Input:
  653. * Returns:
  654. * NULL failure, otherwise returns a new
  655. * ACLListHandle
  656. */
  657. NSAPI_PUBLIC ACLListHandle_t *
  658. ACL_ListNew(NSErr_t *errp)
  659. {
  660. ACLListHandle_t *handle;
  661. handle = ( ACLListHandle_t * ) PERM_CALLOC ( sizeof(ACLListHandle_t) );
  662. handle->ref_count = 1;
  663. return(handle);
  664. }
  665. /*
  666. * Allocates a handle for an ACL wrapper
  667. *
  668. * This wrapper is just used for ACL list creation. It's a way of
  669. * linking ACLs into a list. This is an internal function.
  670. */
  671. static ACLWrapper_t *
  672. acl_wrapper_new(void)
  673. {
  674. ACLWrapper_t *handle;
  675. handle = ( ACLWrapper_t * ) PERM_CALLOC ( sizeof(ACLWrapper_t) );
  676. return(handle);
  677. }
  678. /*
  679. * Description
  680. *
  681. * This function destroys an entry a symbol table entry for an
  682. * ACL.
  683. *
  684. * Arguments:
  685. *
  686. * sym - pointer to Symbol_t for an ACL entry
  687. * argp - unused (must be zero)
  688. *
  689. * Returns:
  690. *
  691. * The return value is SYMENUMREMOVE.
  692. */
  693. static
  694. int acl_hash_entry_destroy(Symbol_t * sym, void * argp)
  695. {
  696. if (sym != 0) {
  697. /* Free the acl name string if any */
  698. if (sym->sym_name != 0) {
  699. PERM_FREE(sym->sym_name);
  700. }
  701. /* Free the Symbol_t structure */
  702. PERM_FREE(sym);
  703. }
  704. /* Indicate that the symbol table entry should be removed */
  705. return SYMENUMREMOVE;
  706. }
  707. /*
  708. * LOCAL FUNCTION
  709. *
  710. * Create a new symbol with the sym_name equal to the
  711. * acl->tag value. Attaches the acl to the sym_data
  712. * pointer.
  713. */
  714. static Symbol_t *
  715. acl_sym_new(ACLHandle_t *acl)
  716. {
  717. Symbol_t *sym;
  718. /* It's not there, so add it */
  719. sym = (Symbol_t *) PERM_MALLOC(sizeof(Symbol_t));
  720. if ( sym == NULL )
  721. return(NULL);
  722. sym->sym_name = PERM_STRDUP(acl->tag);
  723. if ( sym->sym_name == NULL ) {
  724. PERM_FREE(sym);
  725. return(NULL);
  726. }
  727. sym->sym_type = ACLSYMACL;
  728. sym->sym_data = (void *) acl;
  729. return(sym);
  730. }
  731. /*
  732. * LOCAL FUNCTION
  733. *
  734. * Add a acl symbol to an acl_list's symbol table.
  735. *
  736. * Each acl list has a symbol table. the symbol table
  737. * is a quick qay to reference named acl's
  738. */
  739. static int
  740. acl_sym_add(ACLListHandle_t *acl_list, ACLHandle_t *acl)
  741. {
  742. Symbol_t *sym;
  743. int rv;
  744. if ( acl->tag == NULL )
  745. return(ACLERRUNDEF);
  746. rv = symTableFindSym(acl_list->acl_sym_table,
  747. acl->tag,
  748. ACLSYMACL,
  749. (void **)&sym);
  750. if ( rv == SYMERRNOSYM ) {
  751. sym = acl_sym_new(acl);
  752. if ( sym )
  753. rv = symTableAddSym(acl_list->acl_sym_table, sym, (void *)sym);
  754. }
  755. if ( sym == NULL || rv < 0 )
  756. return(ACLERRUNDEF);
  757. return(0);
  758. }
  759. /*
  760. * LOCAL FUNCTION
  761. *
  762. * Destroy an acl_list's symbol table and all memory referenced
  763. * by the symbol table. This does not destroy an acl_list.
  764. */
  765. static void
  766. acl_symtab_destroy(ACLListHandle_t *acl_list)
  767. {
  768. /* Destroy each entry in the symbol table */
  769. symTableEnumerate(acl_list->acl_sym_table, 0, acl_hash_entry_destroy);
  770. /* Destory the hash table itself */
  771. symTableDestroy(acl_list->acl_sym_table, 0);
  772. acl_list->acl_sym_table = NULL;
  773. return;
  774. }
  775. /*
  776. * Appends to a specified ACL
  777. *
  778. * This function appends a specified ACL to the end of a given ACL list.
  779. *
  780. * Input:
  781. * errp The error stack
  782. * flags should always be zero now
  783. * acl_list target ACL list
  784. * acl new acl
  785. * Returns:
  786. * > 0 The number of acl's in the current list
  787. * < 0 failure
  788. */
  789. NSAPI_PUBLIC int
  790. ACL_ListAppend( NSErr_t *errp, ACLListHandle_t *acl_list, ACLHandle_t *acl,
  791. int flags )
  792. {
  793. ACLWrapper_t *wrapper;
  794. ACLHandle_t *tmp_acl;
  795. if ( acl_list == NULL || acl == NULL )
  796. return(ACLERRUNDEF);
  797. if ( acl_list->acl_sym_table == NULL &&
  798. acl_list->acl_count == ACL_TABLE_THRESHOLD ) {
  799. /*
  800. * The symbol table isn't really critical so we don't log
  801. * an error if its creation fails.
  802. */
  803. symTableNew(&acl_list->acl_sym_table);
  804. if ( acl_list->acl_sym_table ) {
  805. for (wrapper = acl_list->acl_list_head; wrapper;
  806. wrapper = wrapper->wrap_next ) {
  807. tmp_acl = wrapper->acl;
  808. if ( acl_sym_add(acl_list, tmp_acl) ) {
  809. acl_symtab_destroy(acl_list);
  810. break;
  811. }
  812. }
  813. }
  814. }
  815. wrapper = acl_wrapper_new();
  816. if ( wrapper == NULL )
  817. return(ACLERRNOMEM);
  818. wrapper->acl = acl;
  819. if ( acl_list->acl_list_head == NULL ) {
  820. acl_list->acl_list_head = wrapper;
  821. acl_list->acl_list_tail = wrapper;
  822. } else {
  823. acl_list->acl_list_tail->wrap_next = wrapper;
  824. acl_list->acl_list_tail = wrapper;
  825. }
  826. acl->ref_count++;
  827. acl_list->acl_count++;
  828. if ( acl_list->acl_sym_table ) {
  829. /*
  830. * If we fail to insert the ACL then we
  831. * might as well destroy this hash table since it is
  832. * useless.
  833. */
  834. if ( acl_sym_add(acl_list, acl) ) {
  835. acl_symtab_destroy(acl_list);
  836. }
  837. }
  838. return(acl_list->acl_count);
  839. }
  840. /*
  841. * Concatenates two ACL lists
  842. *
  843. * Attaches all ACLs in acl_list2 to the end of acl_list1. acl_list2
  844. * is left unchanged.
  845. *
  846. * Input:
  847. * errp pointer to the error stack
  848. * acl_list1 target ACL list
  849. * acl_list2 source ACL list
  850. * Output:
  851. * acl_list1 list contains the concatenation of acl_list1
  852. * and acl_list2.
  853. * Returns:
  854. * > 0 Number of ACLs in acl_list1 after concat
  855. * < 0 failure
  856. */
  857. NSAPI_PUBLIC int
  858. ACL_ListConcat( NSErr_t *errp, ACLListHandle_t *acl_list1,
  859. ACLListHandle_t *acl_list2, int flags )
  860. {
  861. ACLWrapper_t *wrapper;
  862. int rv;
  863. if ( acl_list1 == NULL || acl_list2 == NULL )
  864. return(ACLERRUNDEF);
  865. for ( wrapper = acl_list2->acl_list_head;
  866. wrapper != NULL; wrapper = wrapper->wrap_next )
  867. if ( (rv = ACL_ListAppend ( errp, acl_list1, wrapper->acl, 0 )) < 0 )
  868. return(rv);
  869. return(acl_list1->acl_count);
  870. }
  871. /*
  872. * LOCAL FUNCTION
  873. *
  874. * Free up memory associated with and ACLExprEntry. Probably
  875. * only useful internally since we aren't exporting
  876. * this structure.
  877. */
  878. static void
  879. ACL_ExprEntryDestroy( ACLExprEntry_t *entry )
  880. {
  881. LASFlushFunc_t flushp;
  882. if ( entry == NULL )
  883. return;
  884. if ( entry->las_cookie )
  885. /* freeLAS(NULL, entry->attr_name, &entry->las_cookie); */
  886. {
  887. ACL_LasFindFlush( NULL, entry->attr_name, &flushp );
  888. if ( flushp )
  889. ( *flushp )( &entry->las_cookie );
  890. }
  891. if ( entry->attr_name )
  892. PERM_FREE( entry->attr_name );
  893. if ( entry->attr_pattern )
  894. PERM_FREE( entry->attr_pattern );
  895. return;
  896. }
  897. /*
  898. * LOCAL FUNCTION
  899. *
  900. * This function is used to free all the pvalue memory
  901. * in a plist.
  902. */
  903. static void
  904. acl_expr_auth_destroy(char *pname, const void *pvalue, void *user_data)
  905. {
  906. PERM_FREE((char *) pvalue);
  907. return;
  908. }
  909. /*
  910. * Free up memory associated with and ACLExprHandle.
  911. *
  912. * Input:
  913. * expr expression handle to free up
  914. */
  915. NSAPI_PUBLIC void
  916. ACL_ExprDestroy( ACLExprHandle_t *expr )
  917. {
  918. int ii;
  919. if ( expr == NULL )
  920. return;
  921. if ( expr->expr_tag )
  922. PERM_FREE( expr->expr_tag );
  923. if ( expr->expr_argv ) {
  924. for ( ii = 0; ii < expr->expr_argc; ii++ )
  925. if ( expr->expr_argv[ii] )
  926. PERM_FREE( expr->expr_argv[ii] );
  927. PERM_FREE( expr->expr_argv );
  928. }
  929. for ( ii = 0; ii < expr->expr_term_index; ii++ )
  930. ACL_ExprEntryDestroy( &expr->expr_arry[ii] );
  931. if ( expr->expr_auth ) {
  932. PListEnumerate(expr->expr_auth, acl_expr_auth_destroy, NULL);
  933. PListDestroy(expr->expr_auth);
  934. }
  935. PERM_FREE( expr->expr_arry );
  936. PERM_FREE( expr->expr_raw );
  937. PERM_FREE( expr );
  938. return;
  939. }
  940. /*
  941. * Free up memory associated with and ACLHandle.
  942. *
  943. * Input:
  944. * acl target acl
  945. */
  946. NSAPI_PUBLIC void
  947. ACL_AclDestroy(NSErr_t *errp, ACLHandle_t *acl )
  948. {
  949. ACLExprHandle_t *handle;
  950. ACLExprHandle_t *tmp;
  951. if ( acl == NULL )
  952. return;
  953. acl->ref_count--;
  954. if ( acl->ref_count )
  955. return;
  956. if ( acl->tag )
  957. PERM_FREE( acl->tag );
  958. if ( acl->las_name )
  959. PERM_FREE( acl->las_name );
  960. if ( acl->attr_name )
  961. PERM_FREE( acl->attr_name );
  962. handle = acl->expr_list_head;
  963. while ( handle ) {
  964. tmp = handle;
  965. handle = handle->expr_next;
  966. ACL_ExprDestroy( tmp );
  967. }
  968. PERM_FREE(acl);
  969. return;
  970. }
  971. /*
  972. * Destorys a input ACL List
  973. *
  974. * Input:
  975. * acl_list target list
  976. * Output:
  977. * none target list is freed
  978. */
  979. NSAPI_PUBLIC void
  980. ACL_ListDestroy(NSErr_t *errp, ACLListHandle_t *acl_list )
  981. {
  982. ACLWrapper_t *wrapper;
  983. ACLWrapper_t *tmp_wrapper;
  984. ACLHandle_t *tmp_acl;
  985. if ( acl_list == NULL )
  986. return;
  987. if ( acl_list->acl_sym_table ) {
  988. /* Destroy each entry in the symbol table */
  989. symTableEnumerate(acl_list->acl_sym_table, 0, acl_hash_entry_destroy);
  990. /* Destory the hash table itself */
  991. symTableDestroy(acl_list->acl_sym_table, 0);
  992. }
  993. ACL_EvalDestroyContext( (ACLListCache_t *)acl_list->cache );
  994. wrapper = acl_list->acl_list_head;
  995. while ( wrapper ) {
  996. tmp_acl = wrapper->acl;
  997. tmp_wrapper = wrapper;
  998. wrapper = wrapper->wrap_next;
  999. PERM_FREE( tmp_wrapper );
  1000. ACL_AclDestroy(errp, tmp_acl );
  1001. }
  1002. PERM_FREE( acl_list );
  1003. return;
  1004. }
  1005. /*
  1006. * FUNCTION: ACL_ListGetFirst
  1007. *
  1008. * DESCRIPTION:
  1009. *
  1010. * This function is used to start an enumeration of an
  1011. * ACLListHandle_t. It returns an ACLHandle_t* for the first
  1012. * ACL on the list, and initializes a handle supplied by the
  1013. * caller, which is used to track the current position in the
  1014. * enumeration. This function is normally used in a loop
  1015. * such as:
  1016. *
  1017. * ACLListHandle_t *acl_list = <some ACL list>;
  1018. * ACLHandle_t *cur_acl;
  1019. * ACLListEnum_t acl_enum;
  1020. *
  1021. * for (cur_acl = ACL_ListGetFirst(acl_list, &acl_enum);
  1022. * cur_acl != 0;
  1023. * cur_acl = ACL_ListGetNext(acl_list, &acl_enum)) {
  1024. * ...
  1025. * }
  1026. *
  1027. * The caller should guarantee that no ACLs are added or removed
  1028. * from the ACL list during the enumeration.
  1029. *
  1030. * ARGUMENTS:
  1031. *
  1032. * acl_list - handle for the ACL list
  1033. * acl_enum - pointer to uninitialized enumeration handle
  1034. *
  1035. * RETURNS:
  1036. *
  1037. * As described above. If the acl_list argument is null, or the
  1038. * referenced ACL list is empty, the return value is null.
  1039. */
  1040. NSAPI_PUBLIC ACLHandle_t *
  1041. ACL_ListGetFirst(ACLListHandle_t *acl_list, ACLListEnum_t *acl_enum)
  1042. {
  1043. ACLWrapper_t *wrapper;
  1044. ACLHandle_t *acl = 0;
  1045. *acl_enum = 0;
  1046. if (acl_list) {
  1047. wrapper = acl_list->acl_list_head;
  1048. *acl_enum = (ACLListEnum_t)wrapper;
  1049. if (wrapper) {
  1050. acl = wrapper->acl;
  1051. }
  1052. }
  1053. return acl;
  1054. }
  1055. NSAPI_PUBLIC ACLHandle_t *
  1056. ACL_ListGetNext(ACLListHandle_t *acl_list, ACLListEnum_t *acl_enum)
  1057. {
  1058. ACLWrapper_t *wrapper = (ACLWrapper_t *)(*acl_enum);
  1059. ACLHandle_t *acl = 0;
  1060. if (wrapper) {
  1061. wrapper = wrapper->wrap_next;
  1062. *acl_enum = (ACLListEnum_t)wrapper;
  1063. if (wrapper) acl = wrapper->acl;
  1064. }
  1065. return acl;
  1066. }
  1067. /*
  1068. * FUNCTION: ACL_AclGetTag
  1069. *
  1070. * DESCRIPTION:
  1071. *
  1072. * Returns the tag string associated with an ACL.
  1073. *
  1074. * ARGUMENTS:
  1075. *
  1076. * acl - handle for an ACL
  1077. *
  1078. * RETURNS:
  1079. *
  1080. * The return value is a pointer to the ACL tag string.
  1081. */
  1082. NSAPI_PUBLIC const char *
  1083. ACL_AclGetTag(ACLHandle_t *acl)
  1084. {
  1085. return (acl) ? (const char *)(acl->tag) : 0;
  1086. }
  1087. /*
  1088. * Finds a named ACL in an input list.
  1089. *
  1090. * Input:
  1091. * acl_list a list of ACLs to search
  1092. * acl_name the name of the ACL to find
  1093. * flags e.g. ACL_CASE_INSENSITIVE
  1094. * Returns:
  1095. * NULL No ACL found
  1096. * acl A pointer to an ACL with named acl_name
  1097. */
  1098. NSAPI_PUBLIC ACLHandle_t *
  1099. ACL_ListFind (NSErr_t *errp, ACLListHandle_t *acl_list, char *acl_name, int flags )
  1100. {
  1101. ACLHandle_t *result = NULL;
  1102. ACLWrapper_t *wrapper;
  1103. Symbol_t *sym;
  1104. if ( acl_list == NULL || acl_name == NULL )
  1105. return( result );
  1106. /*
  1107. * right now the symbol table exists if there hasn't been
  1108. * any collisions based on using case insensitive names.
  1109. * if there are any collisions then the table will be
  1110. * deleted and we will look up using list search.
  1111. *
  1112. * we should probably create two hash tables, one for case
  1113. * sensitive lookups and the other for insensitive.
  1114. */
  1115. if ( acl_list->acl_sym_table ) {
  1116. if ( symTableFindSym(acl_list->acl_sym_table,
  1117. acl_name, ACLSYMACL, (void **) &sym) >= 0 ) {
  1118. result = (ACLHandle_t *) sym->sym_data;
  1119. if ( result && (flags & ACL_CASE_SENSITIVE) &&
  1120. strcmp(result->tag, acl_name) ) {
  1121. result = NULL; /* case doesn't match */
  1122. }
  1123. }
  1124. return( result );
  1125. }
  1126. if ( flags & ACL_CASE_INSENSITIVE ) {
  1127. for ( wrapper = acl_list->acl_list_head; wrapper != NULL;
  1128. wrapper = wrapper->wrap_next ) {
  1129. if ( wrapper->acl->tag &&
  1130. strcasecmp( wrapper->acl->tag, acl_name ) == 0 ) {
  1131. result = wrapper->acl;
  1132. break;
  1133. }
  1134. }
  1135. } else {
  1136. for ( wrapper = acl_list->acl_list_head; wrapper != NULL;
  1137. wrapper = wrapper->wrap_next ) {
  1138. if ( wrapper->acl->tag &&
  1139. strcmp( wrapper->acl->tag, acl_name ) == 0 ) {
  1140. result = wrapper->acl;
  1141. break;
  1142. }
  1143. }
  1144. }
  1145. return( result );
  1146. }
  1147. /*
  1148. * Function parses an input ACL file and resturns an
  1149. * ACLListHandle_t pointer that represents the entire
  1150. * file without the comments.
  1151. *
  1152. * Input:
  1153. * filename the name of the target ACL text file
  1154. * errp a pointer to an error stack
  1155. *
  1156. * Returns:
  1157. * NULL parse failed
  1158. *
  1159. */
  1160. NSAPI_PUBLIC ACLListHandle_t *
  1161. ACL_ParseFile( NSErr_t *errp, char *filename )
  1162. {
  1163. ACLListHandle_t *handle = NULL;
  1164. int eid = 0;
  1165. int rv = 0;
  1166. char *errmsg;
  1167. ACL_InitAttr2Index();
  1168. if ( acl_parse_crit == NULL )
  1169. acl_parse_crit = crit_init();
  1170. crit_enter( acl_parse_crit );
  1171. if ( acl_InitScanner( errp, filename, NULL ) < 0 ) {
  1172. rv = ACLERROPEN;
  1173. eid = ACLERR1900;
  1174. errmsg = system_errmsg();
  1175. nserrGenerate(errp, rv, eid, ACL_Program, 2, filename, errmsg);
  1176. } else {
  1177. handle = ACL_ListNew(errp);
  1178. if ( handle == NULL ) {
  1179. rv = ACLERRNOMEM;
  1180. eid = ACLERR1920;
  1181. nserrGenerate(errp, rv, eid, ACL_Program, 0);
  1182. } else if ( acl_PushListHandle( handle ) < 0 ) {
  1183. rv = ACLERRNOMEM;
  1184. eid = ACLERR1920;
  1185. nserrGenerate(errp, rv, eid, ACL_Program, 0);
  1186. } else if ( acl_Parse() ) {
  1187. rv = ACLERRPARSE;
  1188. eid = ACLERR1780;
  1189. }
  1190. if ( acl_EndScanner() < 0 ) {
  1191. rv = ACLERROPEN;
  1192. eid = ACLERR1500;
  1193. errmsg = system_errmsg();
  1194. nserrGenerate(errp, rv, eid, ACL_Program, 2, filename, errmsg);
  1195. }
  1196. }
  1197. if ( rv || eid ) {
  1198. ACL_ListDestroy(errp, handle);
  1199. handle = NULL;
  1200. }
  1201. crit_exit( acl_parse_crit );
  1202. return(handle);
  1203. }
  1204. /*
  1205. * Function parses an input ACL string and returns an
  1206. * ACLListHandle_t pointer that represents the entire
  1207. * file without the comments.
  1208. *
  1209. * Input:
  1210. * buffer the target ACL buffer
  1211. * errp a pointer to an error stack
  1212. *
  1213. * Returns:
  1214. * NULL parse failed
  1215. *
  1216. */
  1217. NSAPI_PUBLIC ACLListHandle_t *
  1218. ACL_ParseString( NSErr_t *errp, char *buffer )
  1219. {
  1220. ACLListHandle_t *handle = NULL;
  1221. int eid = 0;
  1222. int rv = 0;
  1223. char *errmsg;
  1224. ACL_InitAttr2Index();
  1225. if ( acl_parse_crit == NULL )
  1226. acl_parse_crit = crit_init();
  1227. crit_enter( acl_parse_crit );
  1228. if ( acl_InitScanner( errp, NULL, buffer ) < 0 ) {
  1229. rv = ACLERRNOMEM;
  1230. eid = ACLERR1920;
  1231. nserrGenerate(errp, rv, eid, ACL_Program, 0);
  1232. } else {
  1233. handle = ACL_ListNew(errp);
  1234. if ( handle == NULL ) {
  1235. rv = ACLERRNOMEM;
  1236. eid = ACLERR1920;
  1237. nserrGenerate(errp, rv, eid, ACL_Program, 0);
  1238. } else if ( acl_PushListHandle( handle ) < 0 ) {
  1239. rv = ACLERRNOMEM;
  1240. eid = ACLERR1920;
  1241. nserrGenerate(errp, rv, eid, ACL_Program, 0);
  1242. } else if ( acl_Parse() ) {
  1243. rv = ACLERRPARSE;
  1244. eid = ACLERR1780;
  1245. }
  1246. if ( acl_EndScanner() < 0 ) {
  1247. rv = ACLERROPEN;
  1248. eid = ACLERR1500;
  1249. errmsg = system_errmsg();
  1250. nserrGenerate(errp, rv, eid, ACL_Program, 2, "buffer", errmsg);
  1251. }
  1252. }
  1253. if ( rv || eid ) {
  1254. ACL_ListDestroy(errp, handle);
  1255. handle = NULL;
  1256. }
  1257. crit_exit( acl_parse_crit );
  1258. return(handle);
  1259. }
  1260. /*
  1261. * LOCAL FUNCTION
  1262. *
  1263. * Convert sub-expression to string.
  1264. */
  1265. static int
  1266. acl_expr_string( ACLExprOp_t logical, ACLExprStack_t *expr_stack )
  1267. {
  1268. char **expr_text;
  1269. char **prev_expr_text;
  1270. char *tmp;
  1271. switch (logical) {
  1272. case ACL_EXPR_OP_NOT:
  1273. if ( expr_stack->stack_index < 1 ) {
  1274. printf("expression stack underflow.\n");
  1275. return(ACLERRINTERNAL);
  1276. }
  1277. expr_text = &expr_stack->expr_text[expr_stack->stack_index - 1];
  1278. tmp = (char *) PERM_MALLOC(strlen(*expr_text) + 7);
  1279. if ( tmp == NULL )
  1280. return(ACLERRNOMEM);
  1281. if ( expr_stack->found_subexpression ) {
  1282. sprintf(tmp, "not (%s)", *expr_text);
  1283. expr_stack->found_subexpression = 0;
  1284. expr_stack->last_subexpression = expr_stack->stack_index - 1;
  1285. } else {
  1286. sprintf(tmp, "not %s", *expr_text);
  1287. }
  1288. PERM_FREE(*expr_text);
  1289. *expr_text = tmp;
  1290. return(0);
  1291. case ACL_EXPR_OP_AND:
  1292. case ACL_EXPR_OP_OR:
  1293. if ( expr_stack->stack_index < 2 ) {
  1294. printf("expression stack underflow.\n");
  1295. return(ACLERRINTERNAL);
  1296. }
  1297. expr_stack->stack_index--;
  1298. prev_expr_text = &expr_stack->expr_text[expr_stack->stack_index];
  1299. expr_stack->stack_index--;
  1300. expr_text = &expr_stack->expr_text[expr_stack->stack_index];
  1301. tmp = (char *) PERM_MALLOC (strlen(*expr_text)
  1302. + strlen(*prev_expr_text) + 15);
  1303. if ( tmp == NULL )
  1304. return(ACLERRNOMEM);
  1305. if ( expr_stack->found_subexpression &&
  1306. expr_stack->stack_index == expr_stack->last_subexpression &&
  1307. logical == ACL_EXPR_OP_AND ) {
  1308. sprintf(tmp, "%s and\n (%s)", *expr_text, *prev_expr_text);
  1309. } else if ( expr_stack->found_subexpression &&
  1310. expr_stack->stack_index == expr_stack->last_subexpression ) {
  1311. sprintf(tmp, "%s or\n (%s)", *expr_text, *prev_expr_text);
  1312. } else if ( logical == ACL_EXPR_OP_AND ) {
  1313. sprintf(tmp, "%s and\n %s", *expr_text, *prev_expr_text);
  1314. } else {
  1315. sprintf(tmp, "%s or\n %s", *expr_text, *prev_expr_text);
  1316. }
  1317. expr_stack->found_subexpression++;
  1318. expr_stack->stack_index++;
  1319. PERM_FREE(*expr_text);
  1320. PERM_FREE(*prev_expr_text);
  1321. *expr_text = tmp;
  1322. *prev_expr_text = NULL;
  1323. return(0);
  1324. default:
  1325. printf("Bad boolean logic value.\n");
  1326. return(ACLERRINTERNAL);
  1327. }
  1328. }
  1329. /*
  1330. * LOCAL FUNCTION
  1331. *
  1332. * Reduce all sub-expressions to a single string.
  1333. */
  1334. static int
  1335. acl_reduce_expr_logic( ACLExprStack_t *expr_stack, ACLExprRaw_t *expr_raw )
  1336. {
  1337. char **expr_text;
  1338. char **prev_expr_text;
  1339. char *tmp;
  1340. if (expr_raw->attr_name) {
  1341. if (expr_stack->stack_index >= ACL_EXPR_STACK ) {
  1342. printf("expression stack overflow.");
  1343. return(ACLERRINTERNAL);
  1344. }
  1345. if ( expr_stack->found_subexpression && expr_stack->stack_index > 0 ) {
  1346. prev_expr_text = &expr_stack->expr_text[expr_stack->stack_index-1];
  1347. tmp = (char *) PERM_MALLOC(strlen(*prev_expr_text) + 3);
  1348. sprintf(tmp, "(%s)", *prev_expr_text);
  1349. PERM_FREE(*prev_expr_text);
  1350. *prev_expr_text = tmp;
  1351. expr_stack->found_subexpression = 0;
  1352. expr_stack->last_subexpression = expr_stack->stack_index - 1;
  1353. }
  1354. expr_stack->expr[expr_stack->stack_index] = expr_raw;
  1355. expr_text = &expr_stack->expr_text[expr_stack->stack_index];
  1356. *expr_text = (char *) PERM_MALLOC(strlen(expr_raw->attr_name)
  1357. + strlen(expr_raw->attr_pattern)
  1358. + 7);
  1359. if ( *expr_text == NULL )
  1360. return(ACLERRNOMEM);
  1361. sprintf(*expr_text, "%s %s \"%s\"", expr_raw->attr_name,
  1362. acl_comp_string(expr_raw->comparator),
  1363. expr_raw->attr_pattern);
  1364. expr_stack->stack_index++;
  1365. expr_stack->expr_text[expr_stack->stack_index] = NULL;
  1366. } else {
  1367. return(acl_expr_string(expr_raw->logical, expr_stack));
  1368. }
  1369. return(0);
  1370. }
  1371. /*
  1372. * LOCAL FUNCTION
  1373. *
  1374. * Appends str2 to str1.
  1375. *
  1376. * Input:
  1377. * str1 an existing dynamically allocated string
  1378. * str2 a text string
  1379. * Returns:
  1380. * 0 success
  1381. * < 0 failure
  1382. */
  1383. static int
  1384. acl_to_str_append(acl_string_t * p_aclstr, const char *str2)
  1385. {
  1386. int str2len, newlen;
  1387. if (p_aclstr == NULL || str2 == NULL)
  1388. return (ACLERRINTERNAL);
  1389. if (p_aclstr->str == NULL) {
  1390. p_aclstr->str = (char *) PERM_MALLOC(4096);
  1391. if (p_aclstr->str == NULL)
  1392. return (ACLERRNOMEM);
  1393. p_aclstr->str_size = 4096;
  1394. p_aclstr->str_len = 0;
  1395. }
  1396. str2len = strlen(str2);
  1397. newlen = p_aclstr->str_len + str2len;
  1398. if (newlen >= p_aclstr->str_size) {
  1399. p_aclstr->str_size = str2len > 4095 ? str2len+p_aclstr->str_size+1 : 4096+p_aclstr->str_size ;
  1400. p_aclstr->str = (char *) PERM_REALLOC(p_aclstr->str, p_aclstr->str_size);
  1401. if (p_aclstr->str == NULL)
  1402. return (ACLERRNOMEM);
  1403. }
  1404. memcpy((void *)&(p_aclstr->str[p_aclstr->str_len]), (void *) str2, str2len+1);
  1405. p_aclstr->str_len += str2len;
  1406. return 0;
  1407. }
  1408. /*
  1409. * LOCAL FUNCTION
  1410. *
  1411. * Output Authorization Expression type either "Allow" or "Deny"
  1412. */
  1413. static int
  1414. acl_to_str_expr_type( acl_string_t *str_t, ACLExprHandle_t *expr )
  1415. {
  1416. switch (expr->expr_type) {
  1417. case ACL_EXPR_TYPE_ALLOW:
  1418. acl_to_str_append(str_t, "allow ");
  1419. if ( IS_ABSOLUTE(expr->expr_flags) )
  1420. acl_to_str_append(str_t, "absolute ");
  1421. return(0);
  1422. case ACL_EXPR_TYPE_DENY:
  1423. acl_to_str_append(str_t, "deny ");
  1424. if ( IS_ABSOLUTE(expr->expr_flags) )
  1425. acl_to_str_append(str_t, "absolute ");
  1426. return(0);
  1427. case ACL_EXPR_TYPE_AUTH:
  1428. acl_to_str_append(str_t, "authenticate ");
  1429. if ( IS_ABSOLUTE(expr->expr_flags) )
  1430. acl_to_str_append(str_t, "absolute ");
  1431. return(0);
  1432. case ACL_EXPR_TYPE_RESPONSE:
  1433. acl_to_str_append(str_t, "deny with ");
  1434. return(0);
  1435. default:
  1436. return(ACLERRINTERNAL);
  1437. }
  1438. }
  1439. /*
  1440. * LOCAL FUNCTION
  1441. *
  1442. * Output Authorization Expression Rights "(right, right)"
  1443. */
  1444. static int
  1445. acl_to_str_expr_arg( acl_string_t *str_t, ACLExprHandle_t *expr )
  1446. {
  1447. int ii;
  1448. if ( expr->expr_argc <= 0 ) {
  1449. return(ACLERRINTERNAL);
  1450. }
  1451. if ( expr->expr_type == ACL_EXPR_TYPE_RESPONSE ) {
  1452. acl_to_str_append(str_t, expr->expr_argv[0]);
  1453. acl_to_str_append(str_t, "=\"");
  1454. acl_to_str_append(str_t, expr->expr_argv[1]);
  1455. acl_to_str_append(str_t, "\";\n");
  1456. return(0);
  1457. }
  1458. acl_to_str_append(str_t, "(");
  1459. for (ii = 0; ii < expr->expr_argc; ii++) {
  1460. acl_to_str_append(str_t, expr->expr_argv[ii]);
  1461. if ( ii < expr->expr_argc - 1 ) {
  1462. acl_to_str_append(str_t, ",");
  1463. }
  1464. }
  1465. acl_to_str_append(str_t, ") ");
  1466. return(0);
  1467. }
  1468. /*
  1469. * LOCAL FUNCTION
  1470. *
  1471. * Walks through the authentication statement PList_t and
  1472. * prints the structure to a string.
  1473. */
  1474. static void
  1475. acl_to_str_auth_expr(char *lval, const void *rval, void *user_data)
  1476. {
  1477. // ###### char **str = (char **) user_data;
  1478. acl_string_t * p_aclstr = (acl_string_t *) user_data;
  1479. acl_to_str_append(p_aclstr, "\t");
  1480. acl_to_str_append(p_aclstr, lval);
  1481. acl_to_str_append(p_aclstr, " = \"");
  1482. acl_to_str_append(p_aclstr, (char *) rval);
  1483. acl_to_str_append(p_aclstr, "\";\n");
  1484. return;
  1485. }
  1486. /*
  1487. * LOCAL FUNCTION
  1488. *
  1489. * Output the logic part of the authencation statement to a string.
  1490. */
  1491. static int
  1492. acl_to_str_auth_logic( acl_string_t *str_t, ACLExprHandle_t *expr)
  1493. {
  1494. if ( expr->expr_auth == NULL ) {
  1495. acl_to_str_append(str_t, "{\n");
  1496. acl_to_str_append(str_t, "# Authenticate statement with no body?\n");
  1497. acl_to_str_append(str_t, "\tnull=null;\n");
  1498. acl_to_str_append(str_t, "};\n");
  1499. return(0);
  1500. }
  1501. acl_to_str_append(str_t, "{\n");
  1502. PListEnumerate(expr->expr_auth, acl_to_str_auth_expr, (void *) str_t);
  1503. acl_to_str_append(str_t, "};\n");
  1504. return(0);
  1505. }
  1506. /*
  1507. * LOCAL FUNCTION
  1508. *
  1509. * Output the logic part of the authorization statement to a string.
  1510. */
  1511. static int
  1512. acl_to_str_expr_logic( acl_string_t *str_t, ACLExprHandle_t *expr, ACLExprStack_t *expr_stack)
  1513. {
  1514. int rv = 0;
  1515. int ii;
  1516. expr_stack->stack_index = 0;
  1517. expr_stack->found_subexpression = 0;
  1518. expr_stack->last_subexpression = -1;
  1519. for (ii = 0; ii < expr->expr_raw_index; ii++) {
  1520. rv = acl_reduce_expr_logic(expr_stack, &expr->expr_raw[ii]);
  1521. if (rv) break;
  1522. }
  1523. if (!rv && expr_stack->expr_text[0]) {
  1524. acl_to_str_append(str_t, "\n ");
  1525. acl_to_str_append(str_t, expr_stack->expr_text[0]);
  1526. acl_to_str_append(str_t, ";\n");
  1527. PERM_FREE(expr_stack->expr_text[0]);
  1528. }
  1529. return(rv);
  1530. }
  1531. /*
  1532. * LOCAL FUNCTION
  1533. *
  1534. * Output an ACL list to a string.
  1535. */
  1536. static int
  1537. acl_to_str_create( acl_string_t *str_t, ACLListHandle_t *acl_list )
  1538. {
  1539. ACLWrapper_t *wrap;
  1540. ACLHandle_t *acl;
  1541. ACLExprHandle_t *expr;
  1542. int rv = 0;
  1543. ACLExprStack_t *expr_stack;
  1544. expr_stack = (ACLExprStack_t *) PERM_MALLOC(sizeof(ACLExprStack_t));
  1545. if ( expr_stack == NULL )
  1546. return(ACLERRNOMEM);
  1547. acl_to_str_append(str_t, "# File automatically written\n");
  1548. acl_to_str_append(str_t, "#\n");
  1549. acl_to_str_append(str_t, "# You may edit this file by hand\n");
  1550. acl_to_str_append(str_t, "#\n\n");
  1551. if ( acl_list->acl_list_head == NULL ) {
  1552. PERM_FREE(expr_stack);
  1553. return(0);
  1554. }
  1555. acl_to_str_append(str_t, "version 3.0;\n");
  1556. for (wrap = acl_list->acl_list_head; wrap && !rv;
  1557. wrap = wrap->wrap_next ) {
  1558. acl = wrap->acl;
  1559. if ( acl->tag ) {
  1560. acl_to_str_append(str_t, "\nacl \"");
  1561. acl_to_str_append(str_t, acl->tag);
  1562. acl_to_str_append(str_t, "\";\n");
  1563. } else {
  1564. acl_to_str_append(str_t, "\nacl;\n");
  1565. }
  1566. for (expr = acl->expr_list_head; expr && rv == 0;
  1567. expr = expr->expr_next ) {
  1568. if ( (rv = acl_to_str_expr_type(str_t, expr)) < 0 )
  1569. break;
  1570. if ( (rv = acl_to_str_expr_arg(str_t, expr)) < 0)
  1571. break;
  1572. switch (expr->expr_type) {
  1573. case ACL_EXPR_TYPE_DENY:
  1574. case ACL_EXPR_TYPE_ALLOW:
  1575. rv = acl_to_str_expr_logic(str_t, expr, expr_stack);
  1576. break;
  1577. case ACL_EXPR_TYPE_AUTH:
  1578. rv = acl_to_str_auth_logic(str_t, expr);
  1579. break;
  1580. case ACL_EXPR_TYPE_RESPONSE:
  1581. break;
  1582. }
  1583. }
  1584. }
  1585. PERM_FREE(expr_stack);
  1586. return(rv);
  1587. }
  1588. /*
  1589. * Creates an ACL text string from an ACL handle
  1590. *
  1591. * Input:
  1592. * errp error stack
  1593. * acl target text string pointer
  1594. * acl_list Source ACL list handle
  1595. * Ouput:
  1596. * acl a chunk of dynamic memory pointing to ACL text
  1597. * Returns:
  1598. * 0 success
  1599. * < 0 failure
  1600. */
  1601. NSAPI_PUBLIC int
  1602. ACL_WriteString(NSErr_t *errp, char **acl, ACLListHandle_t *acl_list)
  1603. {
  1604. int rv;
  1605. acl_string_t str_t = {NULL,0,0};
  1606. if ( acl_list == NULL || acl == NULL )
  1607. return(ACLERRUNDEF);
  1608. rv = acl_to_str_create(&str_t, acl_list);
  1609. *acl = str_t.str;
  1610. return ( rv );
  1611. }
  1612. /*
  1613. * Write an ACL text file from an input ACL list structure.
  1614. *
  1615. * Input:
  1616. * filename name for the output text file
  1617. * acl_list a list of ACLs to convert to text
  1618. * Output:
  1619. * errp an error stack, set if there are errors
  1620. * to report
  1621. * Returns:
  1622. * 0 success
  1623. * ACLERROPEN,
  1624. * ACLERRNOMEM on failure
  1625. */
  1626. NSAPI_PUBLIC int
  1627. ACL_WriteFile( NSErr_t *errp, char *filename, ACLListHandle_t *acl_list )
  1628. {
  1629. int rv;
  1630. int eid;
  1631. char *errmsg;
  1632. #ifdef UTEST
  1633. FILE *ofp;
  1634. #else
  1635. SYS_FILE ofp;
  1636. #endif
  1637. acl_string_t aclstr = {NULL,0,0};
  1638. char *acl_text = NULL;
  1639. if ( filename == NULL || acl_list == NULL ) {
  1640. rv = ACLERROPEN;
  1641. eid = ACLERR1900;
  1642. errmsg = system_errmsg();
  1643. nserrGenerate(errp, rv, eid, ACL_Program, 2, filename, errmsg);
  1644. return(ACLERROPEN);
  1645. }
  1646. #ifdef UTEST
  1647. ofp = fopen(filename, "w");
  1648. if ( ofp == NULL ) {
  1649. #else
  1650. ofp = system_fopenWT(filename);
  1651. if ( ofp == SYS_ERROR_FD ) {
  1652. #endif
  1653. rv = ACLERROPEN;
  1654. eid = ACLERR1900;
  1655. errmsg = system_errmsg();
  1656. nserrGenerate(errp, rv, eid, ACL_Program, 2, filename, errmsg);
  1657. return(ACLERROPEN);
  1658. }
  1659. rv = acl_to_str_create(&aclstr, acl_list);
  1660. acl_text = aclstr.str;
  1661. if ( rv ) {
  1662. eid = ACLERR3000;
  1663. rv = ACLERRNOMEM;
  1664. nserrGenerate(errp, rv, eid, ACL_Program, 0);
  1665. } else {
  1666. #ifdef UTEST
  1667. if (fputs(acl_text, ofp) == 0) {
  1668. #else
  1669. if (system_fwrite_atomic(ofp, acl_text, strlen(acl_text))==IO_ERROR) {
  1670. #endif
  1671. eid = ACLERR3200;
  1672. rv = ACLERRIO;
  1673. errmsg = system_errmsg();
  1674. nserrGenerate(errp, rv, eid, ACL_Program, 2, filename, errmsg);
  1675. }
  1676. }
  1677. if ( acl_text )
  1678. PERM_FREE(acl_text);
  1679. #ifdef UTEST
  1680. fclose(ofp);
  1681. #else
  1682. system_fclose(ofp);
  1683. #endif
  1684. return(rv);
  1685. }
  1686. /*
  1687. * Delete a named ACL from an ACL list
  1688. *
  1689. * Input:
  1690. * acl_list Target ACL list handle
  1691. * acl_name Name of the target ACL
  1692. * Returns:
  1693. * 0 success
  1694. * < 0 failure
  1695. */
  1696. NSAPI_PUBLIC int
  1697. ACL_ListAclDelete(NSErr_t *errp, ACLListHandle_t *acl_list, char *acl_name, int flags )
  1698. {
  1699. ACLHandle_t *acl = NULL;
  1700. ACLWrapper_t *wrapper;
  1701. ACLWrapper_t *wrapper_prev = NULL;
  1702. Symbol_t *sym;
  1703. if ( acl_list == NULL || acl_name == NULL )
  1704. return(ACLERRUNDEF);
  1705. if ( flags & ACL_CASE_INSENSITIVE ) {
  1706. for ( wrapper = acl_list->acl_list_head; wrapper != NULL;
  1707. wrapper = wrapper->wrap_next ) {
  1708. if ( wrapper->acl->tag &&
  1709. strcasecmp( wrapper->acl->tag, acl_name ) == 0 ) {
  1710. acl = wrapper->acl;
  1711. break;
  1712. }
  1713. wrapper_prev = wrapper;
  1714. }
  1715. } else {
  1716. for ( wrapper = acl_list->acl_list_head; wrapper != NULL;
  1717. wrapper = wrapper->wrap_next ) {
  1718. if ( wrapper->acl->tag &&
  1719. strcmp( wrapper->acl->tag, acl_name ) == 0 ) {
  1720. acl = wrapper->acl;
  1721. break;
  1722. }
  1723. wrapper_prev = wrapper;
  1724. }
  1725. }
  1726. if ( acl ) {
  1727. if ( wrapper_prev ) {
  1728. wrapper_prev->wrap_next = wrapper->wrap_next;
  1729. } else {
  1730. acl_list->acl_list_head = wrapper->wrap_next;
  1731. }
  1732. if ( acl_list->acl_list_tail == wrapper ) {
  1733. acl_list->acl_list_tail = wrapper_prev;
  1734. }
  1735. acl = wrapper->acl;
  1736. acl_list->acl_count--;
  1737. PERM_FREE(wrapper);
  1738. if ( acl_list->acl_sym_table ) {
  1739. if ( symTableFindSym(acl_list->acl_sym_table,
  1740. acl->tag, ACLSYMACL, (void **) &sym) < 0 ) {
  1741. /* not found, this is an error of some sort */
  1742. } else {
  1743. symTableRemoveSym(acl_list->acl_sym_table, sym);
  1744. acl_hash_entry_destroy(sym, 0);
  1745. }
  1746. }
  1747. ACL_AclDestroy(errp, acl);
  1748. return(0);
  1749. }
  1750. return(ACLERRUNDEF);
  1751. }
  1752. /*
  1753. * local function: translate string to lower case
  1754. * return <0: fail
  1755. * 0: succeed
  1756. */
  1757. int
  1758. open_file_buf(FILE ** file, char * filename, char *mode, char ** buf, long * size)
  1759. {
  1760. int rv = 0;
  1761. long cur = 0;
  1762. long in = 0;
  1763. struct stat fi;
  1764. if (filename==NULL || mode==NULL) {
  1765. rv = ACLERROPEN;
  1766. goto open_cleanup;
  1767. }
  1768. if ((*file=fopen(filename,mode))==NULL) {
  1769. rv = ACLERROPEN;
  1770. goto open_cleanup;
  1771. }
  1772. if (system_stat(filename, &fi)==-1) {
  1773. rv = ACLERROPEN;
  1774. goto open_cleanup;
  1775. }
  1776. *size = fi.st_size;
  1777. if ((*buf=(char *)PERM_MALLOC(*size+1))==NULL) {
  1778. rv = ACLERRNOMEM;
  1779. goto open_cleanup;
  1780. }
  1781. rv = 0;
  1782. while (cur<*size) {
  1783. in=fread(&(*buf)[cur], 1, *size, *file);
  1784. cur = cur+in;
  1785. if (feof(*file)) {
  1786. break;
  1787. }
  1788. if (ferror(*file)) {
  1789. rv = ACLERRIO;
  1790. break;
  1791. }
  1792. }
  1793. if (rv==0)
  1794. (*buf)[cur] = 0;
  1795. open_cleanup:
  1796. if (rv<0) {
  1797. if (*file)
  1798. fclose(*file);
  1799. if (*buf)
  1800. PERM_FREE(*buf);
  1801. }
  1802. return rv;
  1803. }
  1804. /*
  1805. * local function: writes buf to disk and close the file
  1806. */
  1807. void
  1808. close_file_buf(FILE * file, char * filename, char * mode, char * buf)
  1809. {
  1810. if (file==NULL)
  1811. return;
  1812. fclose(file);
  1813. if (strchr(mode, 'w')!=NULL || strchr(mode, 'a')!=NULL) {
  1814. file = fopen(filename, "wb");
  1815. fwrite(buf,1,strlen(buf),file);
  1816. fclose(file);
  1817. }
  1818. PERM_FREE(buf);
  1819. }
  1820. /*
  1821. * local function: translate string to lower case
  1822. */
  1823. char *
  1824. str_tolower(char * string)
  1825. {
  1826. register char * p = string;
  1827. for (; *p; p++)
  1828. *p = tolower(*p);
  1829. return string;
  1830. }
  1831. /*
  1832. * local function: get the first name appear in block
  1833. * return: 0 : not found,
  1834. * 1 : found
  1835. */
  1836. int
  1837. acl_get_first_name(char * block, char ** name, char ** next)
  1838. {
  1839. char bounds[] = "\t \"\';";
  1840. char boundchar;
  1841. char *p=NULL, *q=NULL, *start=NULL, *end=NULL;
  1842. if (block==NULL)
  1843. return 0;
  1844. try_next:
  1845. if ((p=strstr(block, "acl"))!=NULL) {
  1846. // check if this "acl" is the first occurance in this line.
  1847. for (q=p-1; ((q>=block) && *q!='\n'); q--) {
  1848. if (strchr(" \t",*q)==NULL) {
  1849. // if not, try next;
  1850. block = p+3;
  1851. goto try_next;
  1852. }
  1853. }
  1854. p+=3;
  1855. while (strchr(bounds,*p)&&(*p!=0))
  1856. p++;
  1857. if (*p==0)
  1858. return 0;
  1859. boundchar = *(p-1);
  1860. start = p;
  1861. while ((boundchar!=*p)&&(*p!=0)&&(*p!=';'))
  1862. p++;
  1863. if (*p==0)
  1864. return 0;
  1865. end = p;
  1866. *name = (char *)PERM_MALLOC(end-start+1);
  1867. strncpy(*name, start, (end-start));
  1868. (*name)[end-start]=0;
  1869. *next = end;
  1870. return 1;
  1871. }
  1872. return 0;
  1873. }
  1874. /*
  1875. * local function: find the pointer to acl string from the given block
  1876. */
  1877. char *
  1878. acl_strstr(char * block, char * aclname)
  1879. {
  1880. const char set[] = "\t \"\';";
  1881. char * name, * rstr = NULL;
  1882. char * lowerb = block;
  1883. int found = 0;
  1884. if (block==NULL||aclname==NULL)
  1885. return NULL;
  1886. while ((name = strstr(block, aclname))!=NULL && !found) {
  1887. if (name>lowerb) { // This should be true, just in case
  1888. if ((strchr(set,name[-1])!=0) && (strchr(set,name[strlen(aclname)])!=0)) {
  1889. // the other 2 sides are in boundary set, that means, this is an exact match.
  1890. while (&name[-1]>=lowerb) {
  1891. name --;
  1892. if (strchr(set, *name)==0)
  1893. break; // should point to 'l'
  1894. }
  1895. if (name==lowerb)
  1896. return NULL;
  1897. if ((name-2)>=lowerb)
  1898. if ((name[-2]=='a') && (name[-1]=='c') && (*name=='l')) {
  1899. name -= 2; // name point to 'a'
  1900. rstr = name;
  1901. while (TRUE) {
  1902. if (name==lowerb) {
  1903. found = 1;
  1904. break;
  1905. }
  1906. else if (name[-1]==' '||name[-1]=='\t')
  1907. name --;
  1908. else if (name[-1]=='\n') {
  1909. found = 1;
  1910. break;
  1911. }
  1912. else
  1913. break; // acl is not at the head, there are other chars.
  1914. }
  1915. }
  1916. }
  1917. block = name + strlen(aclname);
  1918. }
  1919. }
  1920. return rstr;
  1921. }
  1922. /*
  1923. * local function: find the acl string from mapfile and return its acl structure
  1924. */
  1925. int
  1926. get_acl_from_file(char * filename, char * aclname, ACLListHandle_t ** acllist_pp)
  1927. {
  1928. int rv = 0;
  1929. char * pattern=NULL;
  1930. char header[] = "version 3.0;\n";
  1931. int headerlen = strlen(header);
  1932. long filesize;
  1933. FILE * file;
  1934. char * mirror=NULL, * text=NULL, *nextname=NULL;
  1935. char * block=NULL, * aclhead=NULL, * aclend=NULL;
  1936. *acllist_pp = NULL;
  1937. // build the acl name pattern, which should be acl "..."
  1938. // the ".." is built by acl_to_str_create
  1939. if (aclname==NULL) {
  1940. rv = ACLERRUNDEF;
  1941. goto get_cleanup;
  1942. }
  1943. if ((pattern=(char *)PERM_MALLOC(strlen(aclname) + 1))==NULL) {
  1944. rv = ACLERRNOMEM;
  1945. goto get_cleanup;
  1946. }
  1947. else {
  1948. sprintf(pattern,"%s", aclname);
  1949. str_tolower(pattern);
  1950. }
  1951. /* get the acl text from the mapfile */
  1952. if ((rv=open_file_buf(&file, filename, "rb", &block, &filesize))<0)
  1953. goto get_cleanup;
  1954. if ((mirror = (char *) PERM_MALLOC(filesize+1))==NULL) {
  1955. rv = ACLERRNOMEM;
  1956. goto get_cleanup;
  1957. }
  1958. memcpy(mirror, block, filesize);
  1959. mirror[filesize]=0;
  1960. str_tolower(mirror);
  1961. if ((aclhead = acl_strstr(mirror, pattern))!=NULL) {
  1962. // use mirror to search, then transfer to work on block;
  1963. aclhead = block + (aclhead - mirror);
  1964. acl_get_first_name(aclhead+3, &nextname, &aclend);
  1965. aclend = acl_strstr(aclhead+3, nextname);
  1966. if (aclend == NULL) {
  1967. // this is the last acl in the file
  1968. aclend = &aclhead[strlen(aclhead)];
  1969. }
  1970. int len = aclend - aclhead;
  1971. text = (char *) PERM_MALLOC(len + headerlen + 1);
  1972. sprintf(text, "%s", header);
  1973. memcpy(&text[headerlen], aclhead, len);
  1974. text[headerlen + len] = 0;
  1975. if ((*acllist_pp=ACL_ParseString(NULL, text))==NULL) {
  1976. rv = ACLERRPARSE;
  1977. }
  1978. }
  1979. get_cleanup:
  1980. if (pattern)
  1981. PERM_FREE(pattern);
  1982. if (file)
  1983. close_file_buf(file, filename, "rb", block);
  1984. if (mirror)
  1985. PERM_FREE(mirror);
  1986. if (text)
  1987. PERM_FREE(text);
  1988. if (nextname)
  1989. PERM_FREE(nextname);
  1990. return rv;
  1991. }
  1992. /*
  1993. * local function: delete the acl string from mapfile
  1994. */
  1995. int
  1996. delete_acl_from_file(char * filename, char * aclname)
  1997. {
  1998. char * pattern=NULL;
  1999. char header[] = "version 3.0;\n";
  2000. int headerlen = strlen(header);
  2001. int rv = ACLERRUNDEF;
  2002. long filesize;
  2003. FILE * file;
  2004. char * mirror=NULL, * text=NULL, * nextname=NULL;
  2005. char * block=NULL, * aclhead=NULL, * aclend=NULL;
  2006. int remain;
  2007. // build the acl name pattern, which should be acl "..."
  2008. // the ".." is built by acl_to_str_create
  2009. if (aclname==NULL) {
  2010. rv = ACLERRUNDEF;
  2011. goto delete_cleanup;
  2012. }
  2013. if ((pattern=(char *)PERM_MALLOC(strlen(aclname) + 10))==NULL) {
  2014. rv = ACLERRNOMEM;
  2015. goto delete_cleanup;
  2016. }
  2017. else {
  2018. sprintf(pattern,"%s", aclname);
  2019. str_tolower(pattern);
  2020. }
  2021. /* file the acl text from the mapfile */
  2022. if ((rv=open_file_buf(&file, filename, "rb", &block, &filesize))<0)
  2023. goto delete_cleanup;
  2024. if ((mirror = (char *) PERM_MALLOC(filesize+1))==NULL) {
  2025. rv = ACLERRNOMEM;
  2026. goto delete_cleanup;
  2027. }
  2028. memcpy(mirror, block, filesize);
  2029. mirror[filesize]=0;
  2030. str_tolower(mirror);
  2031. if ((aclhead = acl_strstr(mirror, pattern))!=NULL) {
  2032. // use mirror to search, then transfer to work on block;
  2033. aclhead = block + (aclhead - mirror);
  2034. acl_get_first_name(aclhead+3, &nextname, &aclend);
  2035. aclend = acl_strstr(aclhead+3, nextname);
  2036. if (aclend == NULL) {
  2037. // this is the last acl in the file
  2038. aclend = &aclhead[strlen(aclhead)];
  2039. }
  2040. int len = aclend - aclhead;
  2041. text = (char *) PERM_MALLOC(len + headerlen + 1);
  2042. sprintf(text, "%s", header);
  2043. memcpy(&text[headerlen], aclhead, len);
  2044. text[headerlen + len] = 0;
  2045. if (ACL_ParseString(NULL, text)==NULL) {
  2046. rv = ACLERRPARSE;
  2047. goto delete_cleanup;
  2048. }
  2049. }
  2050. if (aclhead!=NULL) { // found the acl in the map file
  2051. // int filesize = mpfile->Size();
  2052. remain = strlen(aclend);
  2053. if (memcpy(aclhead, aclend, remain)!=NULL)
  2054. rv = 0;
  2055. else
  2056. rv = ACLERRIO;
  2057. aclhead[remain]=0;
  2058. block = (char *) PERM_REALLOC(block, strlen(block)+1);
  2059. }
  2060. else
  2061. rv = ACLERRUNDEF;
  2062. delete_cleanup:
  2063. if (pattern)
  2064. PERM_FREE(pattern);
  2065. if (text)
  2066. PERM_FREE(text);
  2067. if (mirror)
  2068. PERM_FREE(mirror);
  2069. if (nextname)
  2070. PERM_FREE(nextname);
  2071. if (file)
  2072. close_file_buf(file, filename, "wb", block);
  2073. return rv;
  2074. }
  2075. /*
  2076. * local function: append the acl string to file
  2077. */
  2078. int
  2079. append_acl_to_file(char * filename, char * aclname, char * acltext)
  2080. {
  2081. int rv;
  2082. /* acltext has been parsed to verify syntax up to this point */
  2083. char * pattern=NULL;
  2084. char * start=NULL;
  2085. char * block;
  2086. long filesize;
  2087. FILE * file;
  2088. long len;
  2089. if ((pattern=(char *)PERM_MALLOC(strlen(aclname) + 10))==NULL) {
  2090. rv = ACLERRNOMEM;
  2091. goto append_cleanup;
  2092. }
  2093. else {
  2094. sprintf(pattern,"%s", aclname);
  2095. }
  2096. if ((rv=open_file_buf(&file, filename, "rb", &block, &filesize))<0)
  2097. goto append_cleanup;
  2098. // find the begining of acl, skip the version part
  2099. len = strlen(block);
  2100. start = acl_strstr(acltext, pattern);
  2101. if ((block=(char *)PERM_REALLOC(block, len+strlen(start)+1))==NULL) {
  2102. rv = ACLERRNOMEM;
  2103. goto append_cleanup;
  2104. }
  2105. strcat(block, start);
  2106. append_cleanup:
  2107. if (pattern)
  2108. PERM_FREE(pattern);
  2109. if (file)
  2110. close_file_buf(file, filename, "wb", block);
  2111. return rv;
  2112. }
  2113. /*
  2114. * local function: rename the acl name in the file
  2115. */
  2116. int
  2117. rename_acl_in_file(char * filename, char * aclname, char * newname)
  2118. {
  2119. ACLListHandle_t * racllist=NULL;
  2120. char * pattern=NULL;
  2121. char header[] = "version 3.0;\n";
  2122. int headerlen = strlen(header);
  2123. int rv = 0;
  2124. long filesize;
  2125. FILE * file;
  2126. int remain;
  2127. long len;
  2128. char * text=NULL, * mirror=NULL, * nextname=NULL;
  2129. char * block=NULL, * aclhead=NULL, * aclend=NULL;
  2130. char * cut=NULL;
  2131. acl_string_t str_t = {NULL,0,0};
  2132. // build the acl name pattern, which should be acl "..."
  2133. // the ".." is built by acl_to_str_create
  2134. if (aclname==NULL || newname==NULL) {
  2135. rv = ACLERRUNDEF;
  2136. goto rename_cleanup;
  2137. }
  2138. if ((pattern=(char *)PERM_MALLOC(strlen(aclname) + 10))==NULL) {
  2139. rv = ACLERRNOMEM;
  2140. goto rename_cleanup;
  2141. }
  2142. else {
  2143. sprintf(pattern,"%s", aclname);
  2144. str_tolower(pattern);
  2145. }
  2146. // file the acl text from the mapfile
  2147. if ((rv=open_file_buf(&file, filename, "rb", &block, &filesize))<0)
  2148. goto rename_cleanup;
  2149. if ((mirror = (char *) PERM_MALLOC(filesize+1))==NULL) {
  2150. rv = ACLERRNOMEM;
  2151. goto rename_cleanup;
  2152. }
  2153. memcpy(mirror, block, filesize);
  2154. mirror[filesize]=0;
  2155. str_tolower(mirror);
  2156. if ((aclhead = acl_strstr(mirror, pattern))!=NULL) {
  2157. // use mirror to search, then transfer to work on block;
  2158. aclhead = block + (aclhead - mirror);
  2159. acl_get_first_name(aclhead+3, &nextname, &aclend);
  2160. aclend = acl_strstr(aclhead+3, nextname);
  2161. if (aclend == NULL) {
  2162. // this is the last acl in the file
  2163. aclend = &aclhead[strlen(aclhead)];
  2164. }
  2165. len = aclend - aclhead;
  2166. text = (char *) PERM_MALLOC(len + headerlen + 1);
  2167. sprintf(text, "%s", header);
  2168. memcpy(&text[headerlen], aclhead, len);
  2169. text[headerlen + len] = 0;
  2170. if ((racllist=ACL_ParseString(NULL, text))==NULL) {
  2171. rv = ACLERRPARSE;
  2172. goto rename_cleanup;
  2173. }
  2174. }
  2175. if (aclhead!=NULL) { // found the acl in the map file
  2176. remain = strlen(aclend);
  2177. // delete the acltext from where it is
  2178. if (memcpy(aclhead, aclend, remain)!=NULL)
  2179. rv = 0;
  2180. else
  2181. rv = ACLERRUNDEF;
  2182. aclhead[remain] = 0;
  2183. len = strlen(block);
  2184. /* establish the renamed the acl */
  2185. acl_to_str_append(&str_t, "acl \"");
  2186. acl_to_str_append(&str_t, newname);
  2187. acl_to_str_append(&str_t, "\";");
  2188. /* skip acl "..."; the semicollon in the last counts for the +1
  2189. add the rest acl text to str_t */
  2190. cut = strchr(text, ';'); // skip version ...;
  2191. cut = strchr(cut+1, ';') + 1; // skip acl ...;
  2192. if (cut==NULL) {
  2193. rv = ACLERRUNDEF;
  2194. goto rename_cleanup;
  2195. }
  2196. acl_to_str_append(&str_t, cut);
  2197. // acl_to_str_append(&str_t, "\n");
  2198. if ((block=(char *) PERM_REALLOC(block, len + strlen(str_t.str) + 1))==NULL) {
  2199. rv = ACLERRNOMEM;
  2200. goto rename_cleanup;
  2201. }
  2202. // strcat(block, "\n");
  2203. strcat(block, str_t.str);
  2204. }
  2205. else
  2206. rv = ACLERRUNDEF;
  2207. rename_cleanup:
  2208. if (pattern)
  2209. PERM_FREE(pattern);
  2210. if (text)
  2211. PERM_FREE(text);
  2212. if (mirror)
  2213. PERM_FREE(mirror);
  2214. if (nextname)
  2215. PERM_FREE(nextname);
  2216. if (str_t.str)
  2217. PERM_FREE(str_t.str);
  2218. if (file)
  2219. close_file_buf(file, filename, "wb", block);
  2220. return rv;
  2221. }
  2222. /*
  2223. * Retrieves the definition of a named ACL
  2224. *
  2225. * Input:
  2226. * errp a error stack
  2227. * filename Target ACL file
  2228. * acl_name Name of the target ACL
  2229. * acl_text a dynmaically allocated text (result)
  2230. * Output:
  2231. * errp error stack is set on error
  2232. * Returns:
  2233. * 0 success
  2234. * <0 failure
  2235. */
  2236. NSAPI_PUBLIC int
  2237. ACL_FileGetAcl(NSErr_t *errp,
  2238. char *filename,
  2239. char *acl_name,
  2240. // ACLListHandle_t **acllist_p,
  2241. char ** acltext,
  2242. int flags)
  2243. {
  2244. int rv;
  2245. ACLListHandle_t * acllist_p;
  2246. if (acl_parse_crit == NULL)
  2247. acl_parse_crit = crit_init();
  2248. crit_enter( acl_parse_crit );
  2249. rv = get_acl_from_file(filename, acl_name, &acllist_p);
  2250. if (acllist_p == NULL) {
  2251. *acltext = NULL;
  2252. goto get_cleanup;
  2253. }
  2254. /*
  2255. if ((rv=ACL_Decompose(errp, acltext, acllist_p))<0) {
  2256. *acltext = NULL;
  2257. goto get_cleanup;
  2258. }
  2259. */
  2260. if ((rv=ACL_WriteString(errp, acltext, acllist_p))<0) {
  2261. *acltext = NULL;
  2262. goto get_cleanup;
  2263. }
  2264. get_cleanup:
  2265. crit_exit( acl_parse_crit );
  2266. return rv;
  2267. }
  2268. /*
  2269. * Delete a named ACL from an ACL file
  2270. *
  2271. * Input:
  2272. * errp a error stack
  2273. * filename Target ACL file
  2274. * acl_name Name of the target ACL
  2275. * Output:
  2276. * errp error stack is set on error
  2277. * Returns:
  2278. * 0 success
  2279. * < 0 failure
  2280. */
  2281. NSAPI_PUBLIC int
  2282. ACL_FileDeleteAcl(NSErr_t *errp,
  2283. char *filename,
  2284. char *acl_name,
  2285. int flags)
  2286. {
  2287. int rv = 0;
  2288. if ( acl_parse_crit == NULL )
  2289. acl_parse_crit = crit_init();
  2290. crit_enter( acl_parse_crit );
  2291. rv = delete_acl_from_file(filename, acl_name);
  2292. crit_exit( acl_parse_crit );
  2293. return(rv);
  2294. }
  2295. /*
  2296. * Sets the definition of an ACL in an ACL file
  2297. *
  2298. * Input:
  2299. * errp a error stack
  2300. * filename Target ACL file
  2301. * acl_name Name of the target ACL
  2302. * acl_text a string that defines the new ACL
  2303. * Output:
  2304. * errp error stack is set on error
  2305. * Returns:
  2306. * 0 success
  2307. * < 0 failure
  2308. */
  2309. NSAPI_PUBLIC int
  2310. ACL_FileSetAcl(NSErr_t *errp,
  2311. char *filename,
  2312. char *acl_text,
  2313. int flags)
  2314. {
  2315. int rv = 0;
  2316. ACLListHandle_t *new_acl_list = NULL;
  2317. char **acl_name_list = NULL;
  2318. if ( acl_parse_crit == NULL )
  2319. acl_parse_crit = crit_init();
  2320. crit_enter( acl_parse_crit );
  2321. // get the acl name.
  2322. new_acl_list = ACL_ParseString(errp, acl_text);
  2323. if ( new_acl_list == NULL ) {
  2324. rv = ACLERRPARSE;
  2325. goto set_cleanup;
  2326. }
  2327. if ( ACL_ListGetNameList(errp, new_acl_list, &acl_name_list) < 0 ) {
  2328. rv = ACLERRNOMEM;
  2329. goto set_cleanup;
  2330. }
  2331. delete_acl_from_file(filename, acl_name_list[0]);
  2332. rv = append_acl_to_file(filename, acl_name_list[0], acl_text);
  2333. set_cleanup:
  2334. crit_exit( acl_parse_crit );
  2335. if (new_acl_list)
  2336. ACL_ListDestroy(errp, new_acl_list);
  2337. if (acl_name_list)
  2338. free(acl_name_list);
  2339. return(rv);
  2340. }
  2341. /*
  2342. * Rename a named ACL in ACL text file
  2343. *
  2344. * Input:
  2345. * errp a error stack
  2346. * filename Target ACL file
  2347. * acl_name Name of the target ACL
  2348. * new_acl_name New ACL name
  2349. * Output:
  2350. * errp error stack is set on error
  2351. * Returns:
  2352. * 0 success
  2353. * < 0 failure
  2354. */
  2355. NSAPI_PUBLIC int
  2356. ACL_FileRenameAcl(NSErr_t *errp,
  2357. char *filename,
  2358. char *aclname,
  2359. char *newname,
  2360. int flags)
  2361. {
  2362. int rv = 0;
  2363. if ( acl_parse_crit == NULL )
  2364. acl_parse_crit = crit_init();
  2365. crit_enter( acl_parse_crit );
  2366. rv = rename_acl_in_file(filename, aclname, newname);
  2367. crit_exit( acl_parse_crit );
  2368. return(rv);
  2369. }
  2370. //
  2371. // Merge a list of ACLs into one ACL
  2372. //
  2373. // Input:
  2374. // filename the target acl file
  2375. // acl_list ACLs to merge
  2376. // new_acl_name resultant ACL
  2377. // flags currently ignored
  2378. // Returns:
  2379. // 0 success
  2380. // < 0 failure
  2381. //
  2382. NSAPI_PUBLIC int
  2383. ACL_FileMergeAcl(NSErr_t *errp,
  2384. char *filename,
  2385. char **acl_name_list,
  2386. char *new_acl_name,
  2387. int flags)
  2388. {
  2389. ACLListHandle_t *new_acl_list = NULL;
  2390. ACLListHandle_t *tmp_acl_list = NULL;
  2391. int ii;
  2392. int rv;
  2393. ACLHandle_t *tmp_acl;
  2394. ACLHandle_t *new_acl;
  2395. ACLExprHandle_t *expr;
  2396. tmp_acl_list = ACL_ParseFile(errp, filename);
  2397. if ( tmp_acl_list == NULL ) {
  2398. rv = ACLERRPARSE;
  2399. goto cleanup;
  2400. }
  2401. new_acl_list = ACL_ParseFile(errp, filename);
  2402. if ( new_acl_list == NULL ) {
  2403. rv = ACLERRPARSE;
  2404. goto cleanup;
  2405. }
  2406. // first get rid of all the ACLs that will be merged
  2407. for (ii = 0; acl_name_list[ii]; ii++) {
  2408. rv = ACL_ListAclDelete(errp, new_acl_list, acl_name_list[ii], flags);
  2409. if ( rv < 0 )
  2410. goto cleanup;
  2411. }
  2412. // now create ACL to house the merged result
  2413. new_acl = ACL_AclNew(errp, new_acl_name);
  2414. if ( new_acl == NULL ) {
  2415. rv = ACLERRNOMEM;
  2416. goto cleanup;
  2417. }
  2418. rv = ACL_ListAppend(errp, new_acl_list, new_acl, flags);
  2419. if ( rv < 0 )
  2420. goto cleanup;
  2421. for (ii = 0; acl_name_list[ii]; ii++) {
  2422. tmp_acl = ACL_ListFind(errp, tmp_acl_list, acl_name_list[ii], flags);
  2423. if ( tmp_acl == NULL ) {
  2424. rv = ACLERRUNDEF;
  2425. goto cleanup;
  2426. }
  2427. for (expr = tmp_acl->expr_list_head; expr; expr = expr->expr_next) {
  2428. // This call can't really fail unless we pass it a NULL
  2429. // or some memory is corrupt.
  2430. rv = ACL_ExprAppend(errp, new_acl, expr);
  2431. if ( rv < 0 )
  2432. goto cleanup;
  2433. tmp_acl->expr_list_head = expr->expr_next;
  2434. tmp_acl->expr_count--;
  2435. }
  2436. // Last bit of clean up so the destroy routine isn't confused.
  2437. tmp_acl->expr_list_tail = NULL;
  2438. tmp_acl->expr_count = 0;
  2439. }
  2440. rv = ACL_WriteFile(errp, filename, new_acl_list);
  2441. cleanup:
  2442. if ( new_acl_list )
  2443. ACL_ListDestroy(errp, new_acl_list);
  2444. if ( tmp_acl_list )
  2445. ACL_ListDestroy(errp, tmp_acl_list);
  2446. return(rv);
  2447. }
  2448. //
  2449. // Merge a list of ACL files into one ACL file
  2450. //
  2451. // Input:
  2452. // filename the target acl file
  2453. // file_list ACL files to merge
  2454. // flags currently ignored
  2455. // Returns:
  2456. // 0 success
  2457. // < 0 failure
  2458. //
  2459. NSAPI_PUBLIC int
  2460. ACL_FileMergeFile(NSErr_t *errp,
  2461. char *filename,
  2462. char **file_list,
  2463. int flags)
  2464. {
  2465. ACLListHandle_t *new_acl_list = NULL;
  2466. ACLListHandle_t *tmp_acl_list = NULL;
  2467. int ii;
  2468. int rv;
  2469. // we don't care if they have nothing to do
  2470. if ( filename == NULL || file_list == NULL )
  2471. return(0);
  2472. new_acl_list = ACL_ListNew(errp);
  2473. if (new_acl_list == NULL)
  2474. return(ACLERRNOMEM);
  2475. for (ii = 0; file_list[ii]; ii++) {
  2476. tmp_acl_list = ACL_ParseFile(errp, file_list[ii]);
  2477. if (tmp_acl_list == NULL) {
  2478. rv = ACLERRPARSE;
  2479. goto cleanup;
  2480. }
  2481. rv = ACL_ListConcat(errp, new_acl_list, tmp_acl_list, flags);
  2482. if ( rv < 0 )
  2483. goto cleanup;
  2484. ACL_ListDestroy(errp, tmp_acl_list);
  2485. tmp_acl_list = NULL;
  2486. }
  2487. rv = ACL_WriteFile(errp, filename, new_acl_list);
  2488. cleanup:
  2489. if ( new_acl_list )
  2490. ACL_ListDestroy(errp, new_acl_list);
  2491. if ( tmp_acl_list )
  2492. ACL_ListDestroy(errp, tmp_acl_list);
  2493. return(rv);
  2494. }
  2495. /*
  2496. * Destroy a NameList
  2497. *
  2498. * Input:
  2499. * name_list a dynamically allocated array of strings
  2500. * Returns:
  2501. * 0 success
  2502. * < 0 failure
  2503. */
  2504. NSAPI_PUBLIC int
  2505. ACL_NameListDestroy(NSErr_t *errp, char **name_list)
  2506. {
  2507. int list_index;
  2508. if ( name_list == NULL )
  2509. return(ACLERRUNDEF);
  2510. for ( list_index = 0; name_list[list_index]; list_index++ ) {
  2511. PERM_FREE(name_list[list_index]);
  2512. }
  2513. PERM_FREE(name_list);
  2514. return(0);
  2515. }
  2516. /*
  2517. * Gets a name list of consisting of all ACL names for input list.
  2518. *
  2519. * Input:
  2520. * acl_list an ACL List handle
  2521. * name_list pointer to a list of string pointers
  2522. * Returns:
  2523. * 0 success
  2524. * < 0 failure
  2525. */
  2526. NSAPI_PUBLIC int
  2527. ACL_ListGetNameList(NSErr_t *errp, ACLListHandle_t *acl_list, char ***name_list)
  2528. {
  2529. const int block_size = 50;
  2530. ACLWrapper_t *wrapper;
  2531. int list_index;
  2532. int list_size;
  2533. char **tmp_list;
  2534. char **local_list;
  2535. char *name;
  2536. if ( acl_list == NULL )
  2537. return(ACLERRUNDEF);
  2538. list_size = block_size;
  2539. local_list = (char **) PERM_MALLOC(sizeof(char *) * list_size);
  2540. if ( local_list == NULL )
  2541. return(ACLERRNOMEM);
  2542. list_index = 0;
  2543. local_list[list_index] = NULL;
  2544. for ( wrapper = acl_list->acl_list_head; wrapper != NULL;
  2545. wrapper = wrapper->wrap_next ) {
  2546. if ( wrapper->acl->tag )
  2547. name = wrapper->acl->tag;
  2548. else
  2549. name = "noname";
  2550. if ( list_index + 2 > list_size ) {
  2551. list_size += block_size;
  2552. tmp_list = (char **) PERM_REALLOC(local_list,
  2553. sizeof(char *) * list_size);
  2554. if ( tmp_list == NULL ) {
  2555. ACL_NameListDestroy(errp, local_list);
  2556. return(ACLERRNOMEM);
  2557. }
  2558. local_list = tmp_list;
  2559. }
  2560. local_list[list_index] = PERM_STRDUP(name);
  2561. if ( local_list[list_index] == NULL ) {
  2562. ACL_NameListDestroy(errp, local_list);
  2563. return(ACLERRNOMEM);
  2564. }
  2565. list_index++;
  2566. local_list[list_index] = NULL;
  2567. }
  2568. *name_list = local_list;
  2569. return(0);
  2570. }
  2571. /*
  2572. * Gets a name list of consisting of all ACL names from the input aclfile
  2573. *
  2574. * Input:
  2575. * filename acl file
  2576. * name_list pointer to a list of string pointers
  2577. * Returns:
  2578. * 0 success
  2579. * < 0 failure
  2580. */
  2581. NSAPI_PUBLIC int
  2582. ACL_FileGetNameList(NSErr_t *errp, char * filename, char ***name_list)
  2583. {
  2584. const int block_size = 50;
  2585. int rv, list_size, list_index;
  2586. char ** local_list;
  2587. char * block ;
  2588. char * name;
  2589. char * next;
  2590. long filesize;
  2591. FILE * file;
  2592. char * head;
  2593. if ((rv=open_file_buf(&file, filename, "rb", &block, &filesize))<0)
  2594. goto list_cleanup;
  2595. list_size = block_size;
  2596. local_list = (char **) PERM_MALLOC(sizeof(char *) * list_size);
  2597. if ( local_list == NULL ) {
  2598. rv = ACLERRNOMEM;
  2599. goto list_cleanup;
  2600. }
  2601. list_index = 0;
  2602. local_list[list_index] = NULL;
  2603. head = block;
  2604. while ((acl_get_first_name(head, &name, &next))) {
  2605. if (list_index+2 > list_size) {
  2606. list_size += block_size;
  2607. char ** tmp_list = (char **) PERM_REALLOC(local_list, sizeof(char *) * list_size);
  2608. if ( tmp_list == NULL ) {
  2609. rv = ACLERRNOMEM;
  2610. goto list_cleanup;
  2611. }
  2612. local_list = tmp_list;
  2613. }
  2614. // local_list[list_index] = PERM_STRDUP(name);
  2615. local_list[list_index] = name;
  2616. if ( local_list[list_index] == NULL ) {
  2617. rv = ACLERRNOMEM;
  2618. goto list_cleanup;
  2619. }
  2620. list_index++;
  2621. local_list[list_index] = NULL;
  2622. head = next;
  2623. }
  2624. rv = 0;
  2625. *name_list = local_list;
  2626. list_cleanup:
  2627. if (local_list && rv<0)
  2628. ACL_NameListDestroy(errp, local_list);
  2629. if (file)
  2630. close_file_buf(file, filename, "rb", block);
  2631. return rv;
  2632. }
  2633. /*
  2634. * Changes method to method plus DBTYPE, and registers
  2635. * databases.
  2636. *
  2637. * Input:
  2638. * errp error stack
  2639. * acl_list Target ACL list handle
  2640. * Returns:
  2641. * 0 success
  2642. * < 0 failure
  2643. */
  2644. NSAPI_PUBLIC int
  2645. ACL_ListPostParseForAuth(NSErr_t *errp, ACLListHandle_t *acl_list )
  2646. {
  2647. ACLHandle_t *acl;
  2648. ACLWrapper_t *wrap;
  2649. ACLExprHandle_t *expr;
  2650. char *method;
  2651. char *database;
  2652. int rv;
  2653. ACLDbType_t *dbtype;
  2654. ACLMethod_t *methodtype;
  2655. if ( acl_list == NULL )
  2656. return(0);
  2657. for ( wrap = acl_list->acl_list_head; wrap; wrap = wrap->wrap_next ) {
  2658. acl = wrap->acl;
  2659. if ( acl == NULL )
  2660. continue;
  2661. for ( expr = acl->expr_list_head; expr; expr = expr->expr_next ) {
  2662. if ( expr->expr_type != ACL_EXPR_TYPE_AUTH ||
  2663. expr->expr_auth == NULL)
  2664. continue;
  2665. rv = PListGetValue(expr->expr_auth, ACL_ATTR_METHOD_INDEX,
  2666. (void **) &method, NULL);
  2667. if ( rv >= 0 ) {
  2668. methodtype = (ACLMethod_t *)PERM_MALLOC(sizeof(ACLMethod_t));
  2669. rv = ACL_MethodFind(errp, method, methodtype);
  2670. if (rv) {
  2671. nserrGenerate(errp, ACLERRUNDEF, ACLERR3800, ACL_Program,
  2672. 3, acl->tag, "method", method);
  2673. PERM_FREE(methodtype);
  2674. return(ACLERRUNDEF);
  2675. }
  2676. rv = PListSetValue(expr->expr_auth, ACL_ATTR_METHOD_INDEX,
  2677. methodtype, NULL);
  2678. if ( rv < 0 ) {
  2679. nserrGenerate(errp, ACLERRNOMEM, ACLERR3810, ACL_Program,
  2680. 0);
  2681. return(ACLERRNOMEM);
  2682. }
  2683. PERM_FREE(method);
  2684. }
  2685. rv = PListGetValue(expr->expr_auth, ACL_ATTR_DATABASE_INDEX,
  2686. (void **) &database, NULL);
  2687. if (rv < 0) continue;
  2688. /* The following function lets user use databases which are
  2689. * not registered by their administrators. This also fixes
  2690. * the backward compatibility.
  2691. */
  2692. dbtype = (ACLDbType_t *)PERM_MALLOC(sizeof(ACLDbType_t));
  2693. rv = ACL_RegisterDbFromACL(errp, (const char *) database,
  2694. dbtype);
  2695. if (rv < 0) {
  2696. nserrGenerate(errp, ACLERRUNDEF, ACLERR3800, ACL_Program,
  2697. 3, acl->tag, "database", database);
  2698. PERM_FREE(dbtype);
  2699. return(ACLERRUNDEF);
  2700. }
  2701. rv = PListInitProp(expr->expr_auth, ACL_ATTR_DBTYPE_INDEX, ACL_ATTR_DBTYPE,
  2702. dbtype, NULL);
  2703. if ( rv < 0 ) {
  2704. nserrGenerate(errp, ACLERRNOMEM, ACLERR3810, ACL_Program,
  2705. 0);
  2706. return(ACLERRNOMEM);
  2707. }
  2708. }
  2709. }
  2710. return(0);
  2711. }
  2712. /*
  2713. * LOCAL FUNCTION
  2714. *
  2715. * Output Authorization Expression Rights "right, right"
  2716. */
  2717. static int
  2718. acl_decompose_expr_arg( acl_string_t *str_t, ACLExprHandle_t *expr )
  2719. {
  2720. int ii;
  2721. if ( expr->expr_argc <= 0 ) {
  2722. return(ACLERRINTERNAL);
  2723. }
  2724. if ( expr->expr_type == ACL_EXPR_TYPE_RESPONSE ) {
  2725. acl_to_str_append(str_t, expr->expr_argv[0]);
  2726. acl_to_str_append(str_t, " \"");
  2727. acl_to_str_append(str_t, expr->expr_argv[1]);
  2728. acl_to_str_append(str_t, "\";\n");
  2729. return(0);
  2730. }
  2731. for (ii = 0; ii < expr->expr_argc; ii++) {
  2732. acl_to_str_append(str_t, expr->expr_argv[ii]);
  2733. if ( ii < expr->expr_argc - 1 ) {
  2734. acl_to_str_append(str_t, ",");
  2735. }
  2736. }
  2737. acl_to_str_append(str_t, ";\n");
  2738. return(0);
  2739. }
  2740. /*
  2741. * LOCAL FUNCTION
  2742. *
  2743. * Walks through the authentication statement PList_t and
  2744. * prints the structure to a string.
  2745. */
  2746. static void
  2747. acl_decompose_auth_expr(char *lval, const void *rval, void *user_data)
  2748. {
  2749. acl_string_t * p_aclstr = (acl_string_t *) user_data;
  2750. // ####
  2751. acl_to_str_append(p_aclstr, " ");
  2752. acl_to_str_append(p_aclstr, lval);
  2753. acl_to_str_append(p_aclstr, "=\"");
  2754. acl_to_str_append(p_aclstr, (char *) rval);
  2755. acl_to_str_append(p_aclstr, "\"");
  2756. return;
  2757. }
  2758. /*
  2759. * LOCAL FUNCTION
  2760. *
  2761. * Output the logic part of the authencation statement to a string.
  2762. */
  2763. static int
  2764. acl_decompose_auth_logic( acl_string_t * str_t, ACLExprHandle_t *expr)
  2765. {
  2766. if ( expr->expr_auth == NULL )
  2767. return(0);
  2768. acl_to_str_append(str_t, "exprs");
  2769. PListEnumerate(expr->expr_auth, acl_decompose_auth_expr, (void *) str_t);
  2770. acl_to_str_append(str_t, ";\n");
  2771. return(0);
  2772. }
  2773. /*
  2774. * LOCAL FUNCTION
  2775. *
  2776. * Output the logic part of the authorization statement to a string.
  2777. */
  2778. static int
  2779. acl_decompose_expr_logic( acl_string_t *str_t, ACLExprHandle_t *expr, ACLExprStack_t *expr_stack)
  2780. {
  2781. int rv = 0;
  2782. int ii;
  2783. expr_stack->stack_index = 0;
  2784. expr_stack->found_subexpression = 0;
  2785. expr_stack->last_subexpression = -1;
  2786. for (ii = 0; ii < expr->expr_raw_index; ii++) {
  2787. rv = acl_reduce_expr_logic(expr_stack, &expr->expr_raw[ii]);
  2788. if (rv) break;
  2789. }
  2790. if (!rv && expr_stack->expr_text[0]) {
  2791. acl_to_str_append(str_t, "exprs ");
  2792. acl_to_str_append(str_t, expr_stack->expr_text[0]);
  2793. acl_to_str_append(str_t, ";\n");
  2794. PERM_FREE(expr_stack->expr_text[0]);
  2795. }
  2796. return(rv);
  2797. }
  2798. static int
  2799. acl_decompose(acl_string_t *str_t, ACLListHandle_t *acl_list)
  2800. {
  2801. ACLWrapper_t *wrap;
  2802. ACLHandle_t *acl;
  2803. ACLExprHandle_t *expr;
  2804. int rv = 0;
  2805. ACLExprStack_t *expr_stack;
  2806. expr_stack = (ACLExprStack_t *) PERM_MALLOC(sizeof(ACLExprStack_t));
  2807. if ( expr_stack == NULL )
  2808. return(ACLERRNOMEM);
  2809. if ( acl_list->acl_list_head == NULL ) {
  2810. PERM_FREE(expr_stack);
  2811. return(0);
  2812. }
  2813. acl_to_str_append(str_t, "version 3.0;");
  2814. for (wrap = acl_list->acl_list_head; wrap && !rv;
  2815. wrap = wrap->wrap_next ) {
  2816. acl = wrap->acl;
  2817. if ( acl->tag ) {
  2818. acl_to_str_append(str_t, "\nname \"");
  2819. acl_to_str_append(str_t, acl->tag);
  2820. acl_to_str_append(str_t, "\";\n");
  2821. } else {
  2822. acl_to_str_append(str_t, "\nname;\n");
  2823. }
  2824. for (expr = acl->expr_list_head; expr && rv == 0;
  2825. expr = expr->expr_next ) {
  2826. switch (expr->expr_type) {
  2827. case ACL_EXPR_TYPE_DENY:
  2828. acl_to_str_append(str_t, "type deny;\nrights ");
  2829. if ( (rv = acl_decompose_expr_arg(str_t, expr)) < 0 )
  2830. break;
  2831. if ( IS_ABSOLUTE(expr->expr_flags) )
  2832. acl_to_str_append(str_t, "absolute true;\n");
  2833. rv = acl_decompose_expr_logic(str_t, expr, expr_stack);
  2834. break;
  2835. case ACL_EXPR_TYPE_ALLOW:
  2836. acl_to_str_append(str_t, "type allow;\nrights ");
  2837. if ( (rv = acl_decompose_expr_arg(str_t, expr)) < 0 )
  2838. break;
  2839. if ( IS_ABSOLUTE(expr->expr_flags) )
  2840. acl_to_str_append(str_t, "absolute true;\n");
  2841. rv = acl_decompose_expr_logic(str_t, expr, expr_stack);
  2842. break;
  2843. case ACL_EXPR_TYPE_AUTH:
  2844. acl_to_str_append(str_t, "type authenticate;\nattrs ");
  2845. if ( (rv = acl_decompose_expr_arg(str_t, expr)) < 0 )
  2846. break;
  2847. if ( IS_ABSOLUTE(expr->expr_flags) )
  2848. acl_to_str_append(str_t, "absolute true;\n");
  2849. rv = acl_decompose_auth_logic(str_t, expr);
  2850. break;
  2851. case ACL_EXPR_TYPE_RESPONSE:
  2852. acl_to_str_append(str_t, "type response;\nattrs ");
  2853. rv = acl_decompose_expr_arg(str_t, expr);
  2854. break;
  2855. }
  2856. }
  2857. }
  2858. PERM_FREE(expr_stack);
  2859. return(rv);
  2860. }
  2861. /*
  2862. * Converts an ACLListHandle_t to a parameter list suitable for passing
  2863. * to the ACL UI.
  2864. *
  2865. * Input:
  2866. * errp error stack
  2867. * acl a pointer to a string, holds the result of the
  2868. * decomposition.
  2869. * acl_list Target ACL list handle
  2870. * Returns:
  2871. * 0 success
  2872. * < 0 failure
  2873. */
  2874. NSAPI_PUBLIC int
  2875. ACL_Decompose(NSErr_t *errp, char **acl, ACLListHandle_t *acl_list)
  2876. {
  2877. int rv ;
  2878. acl_string_t aclstr={NULL,0,0};
  2879. if ( acl_list == NULL || acl == NULL )
  2880. return(ACLERRUNDEF);
  2881. rv = acl_decompose(&aclstr, acl_list);
  2882. *acl = aclstr.str;
  2883. return ( rv );
  2884. }
  2885. /*
  2886. * The following routines are used to validate input parameters. They always
  2887. * return 1, or cause an PR_ASSERT failure. The proper way to use them is
  2888. * with an PR_ASSERT in the calling function. E.g.
  2889. * PR_ASSERT(ACL_AssertAcllist(acllist));
  2890. */
  2891. int
  2892. ACL_AssertAcllist(ACLListHandle_t *acllist)
  2893. {
  2894. ACLWrapper_t *wrap;
  2895. if (acllist == ACL_LIST_NO_ACLS) return 1;
  2896. PR_ASSERT(acllist);
  2897. PR_ASSERT(acllist->acl_list_head);
  2898. PR_ASSERT(acllist->acl_list_tail);
  2899. PR_ASSERT(acllist->acl_count);
  2900. PR_ASSERT(acllist->ref_count > 0);
  2901. for (wrap=acllist->acl_list_head; wrap; wrap=wrap->wrap_next) {
  2902. PR_ASSERT(ACL_AssertAcl(wrap->acl));
  2903. }
  2904. /* Artificially limit ACL lists to 10 ACLs for now */
  2905. PR_ASSERT(acllist->acl_count < 10);
  2906. return 1;
  2907. }
  2908. int
  2909. ACL_AssertAcl(ACLHandle_t *acl)
  2910. {
  2911. PR_ASSERT(acl);
  2912. PR_ASSERT(acl->ref_count);
  2913. PR_ASSERT(acl->expr_count);
  2914. PR_ASSERT(acl->expr_list_head);
  2915. PR_ASSERT(acl->expr_list_tail);
  2916. return 1;
  2917. }
  2918. static PList_t ACLAttr2IndexPList = NULL;
  2919. int
  2920. ACL_InitAttr2Index(void)
  2921. {
  2922. int i;
  2923. if (ACLAttr2IndexPList) return 0;
  2924. ACLAttr2IndexPList = PListNew(NULL);
  2925. for (i = 1; i < ACL_ATTR_INDEX_MAX; i++) {
  2926. PListInitProp(ACLAttr2IndexPList, 0, ACLAttrTable[i], (const void *)i, NULL);
  2927. }
  2928. return 0;
  2929. }
  2930. /*
  2931. * Attempt to locate the index number for one of the known attribute names
  2932. * that are stored in plists. If we can't match it, just return 0.
  2933. */
  2934. int
  2935. ACL_Attr2Index(const char *attrname)
  2936. {
  2937. int index = 0;
  2938. if ( ACLAttr2IndexPList ) {
  2939. PListFindValue(ACLAttr2IndexPList, attrname, (void **)&index, NULL);
  2940. if (index < 0) index = 0;
  2941. }
  2942. return index;
  2943. }