acltools.cpp 81 KB

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