acltools.cpp 83 KB

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