acltools.cpp 66 KB

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