acltools.cpp 83 KB

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