acltools.cpp 43 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778
  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. const 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 const 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. const 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 string and returns an
  1149. * ACLListHandle_t pointer that represents the entire
  1150. * file without the comments.
  1151. *
  1152. * Input:
  1153. * buffer the target ACL buffer
  1154. * errp a pointer to an error stack
  1155. *
  1156. * Returns:
  1157. * NULL parse failed
  1158. *
  1159. */
  1160. NSAPI_PUBLIC ACLListHandle_t *
  1161. ACL_ParseString( NSErr_t *errp, char *buffer )
  1162. {
  1163. ACLListHandle_t *handle = NULL;
  1164. int eid = 0;
  1165. int rv = 0;
  1166. const 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, NULL, buffer ) < 0 ) {
  1172. rv = ACLERRNOMEM;
  1173. eid = ACLERR1920;
  1174. nserrGenerate(errp, rv, eid, ACL_Program, 0);
  1175. } else {
  1176. handle = ACL_ListNew(errp);
  1177. if ( handle == NULL ) {
  1178. rv = ACLERRNOMEM;
  1179. eid = ACLERR1920;
  1180. nserrGenerate(errp, rv, eid, ACL_Program, 0);
  1181. } else if ( acl_PushListHandle( handle ) < 0 ) {
  1182. rv = ACLERRNOMEM;
  1183. eid = ACLERR1920;
  1184. nserrGenerate(errp, rv, eid, ACL_Program, 0);
  1185. } else if ( acl_Parse() ) {
  1186. rv = ACLERRPARSE;
  1187. eid = ACLERR1780;
  1188. }
  1189. if ( acl_EndScanner() < 0 ) {
  1190. rv = ACLERROPEN;
  1191. eid = ACLERR1500;
  1192. errmsg = system_errmsg();
  1193. nserrGenerate(errp, rv, eid, ACL_Program, 2, "buffer", errmsg);
  1194. }
  1195. }
  1196. if ( rv || eid ) {
  1197. ACL_ListDestroy(errp, handle);
  1198. handle = NULL;
  1199. }
  1200. crit_exit( acl_parse_crit );
  1201. return(handle);
  1202. }
  1203. /*
  1204. * Delete a named ACL from an ACL list
  1205. *
  1206. * Input:
  1207. * acl_list Target ACL list handle
  1208. * acl_name Name of the target ACL
  1209. * Returns:
  1210. * 0 success
  1211. * < 0 failure
  1212. */
  1213. NSAPI_PUBLIC int
  1214. ACL_ListAclDelete(NSErr_t *errp, ACLListHandle_t *acl_list, char *acl_name, int flags )
  1215. {
  1216. ACLHandle_t *acl = NULL;
  1217. ACLWrapper_t *wrapper;
  1218. ACLWrapper_t *wrapper_prev = NULL;
  1219. Symbol_t *sym;
  1220. if ( acl_list == NULL || acl_name == NULL )
  1221. return(ACLERRUNDEF);
  1222. if ( flags & ACL_CASE_INSENSITIVE ) {
  1223. for ( wrapper = acl_list->acl_list_head; wrapper != NULL;
  1224. wrapper = wrapper->wrap_next ) {
  1225. if ( wrapper->acl->tag &&
  1226. strcasecmp( wrapper->acl->tag, acl_name ) == 0 ) {
  1227. acl = wrapper->acl;
  1228. break;
  1229. }
  1230. wrapper_prev = wrapper;
  1231. }
  1232. } else {
  1233. for ( wrapper = acl_list->acl_list_head; wrapper != NULL;
  1234. wrapper = wrapper->wrap_next ) {
  1235. if ( wrapper->acl->tag &&
  1236. strcmp( wrapper->acl->tag, acl_name ) == 0 ) {
  1237. acl = wrapper->acl;
  1238. break;
  1239. }
  1240. wrapper_prev = wrapper;
  1241. }
  1242. }
  1243. if ( acl ) {
  1244. if ( wrapper_prev ) {
  1245. wrapper_prev->wrap_next = wrapper->wrap_next;
  1246. } else {
  1247. acl_list->acl_list_head = wrapper->wrap_next;
  1248. }
  1249. if ( acl_list->acl_list_tail == wrapper ) {
  1250. acl_list->acl_list_tail = wrapper_prev;
  1251. }
  1252. acl = wrapper->acl;
  1253. acl_list->acl_count--;
  1254. PERM_FREE(wrapper);
  1255. if ( acl_list->acl_sym_table ) {
  1256. if ( symTableFindSym(acl_list->acl_sym_table,
  1257. acl->tag, ACLSYMACL, (void **) &sym) < 0 ) {
  1258. /* not found, this is an error of some sort */
  1259. } else {
  1260. symTableRemoveSym(acl_list->acl_sym_table, sym);
  1261. acl_hash_entry_destroy(sym, 0);
  1262. }
  1263. }
  1264. ACL_AclDestroy(errp, acl);
  1265. return(0);
  1266. }
  1267. return(ACLERRUNDEF);
  1268. }
  1269. /*
  1270. * Destroy a NameList
  1271. *
  1272. * Input:
  1273. * name_list a dynamically allocated array of strings
  1274. * Returns:
  1275. * 0 success
  1276. * < 0 failure
  1277. */
  1278. NSAPI_PUBLIC int
  1279. ACL_NameListDestroy(NSErr_t *errp, char **name_list)
  1280. {
  1281. int list_index;
  1282. if ( name_list == NULL )
  1283. return(ACLERRUNDEF);
  1284. for ( list_index = 0; name_list[list_index]; list_index++ ) {
  1285. PERM_FREE(name_list[list_index]);
  1286. }
  1287. PERM_FREE(name_list);
  1288. return(0);
  1289. }
  1290. /*
  1291. * Gets a name list of consisting of all ACL names for input list.
  1292. *
  1293. * Input:
  1294. * acl_list an ACL List handle
  1295. * name_list pointer to a list of string pointers
  1296. * Returns:
  1297. * 0 success
  1298. * < 0 failure
  1299. */
  1300. NSAPI_PUBLIC int
  1301. ACL_ListGetNameList(NSErr_t *errp, ACLListHandle_t *acl_list, char ***name_list)
  1302. {
  1303. const int block_size = 50;
  1304. ACLWrapper_t *wrapper;
  1305. int list_index;
  1306. int list_size;
  1307. char **tmp_list;
  1308. char **local_list;
  1309. const char *name;
  1310. if ( acl_list == NULL )
  1311. return(ACLERRUNDEF);
  1312. list_size = block_size;
  1313. local_list = (char **) PERM_MALLOC(sizeof(char *) * list_size);
  1314. if ( local_list == NULL )
  1315. return(ACLERRNOMEM);
  1316. list_index = 0;
  1317. local_list[list_index] = NULL;
  1318. for ( wrapper = acl_list->acl_list_head; wrapper != NULL;
  1319. wrapper = wrapper->wrap_next ) {
  1320. if ( wrapper->acl->tag )
  1321. name = wrapper->acl->tag;
  1322. else
  1323. name = "noname";
  1324. if ( list_index + 2 > list_size ) {
  1325. list_size += block_size;
  1326. tmp_list = (char **) PERM_REALLOC(local_list,
  1327. sizeof(char *) * list_size);
  1328. if ( tmp_list == NULL ) {
  1329. ACL_NameListDestroy(errp, local_list);
  1330. return(ACLERRNOMEM);
  1331. }
  1332. local_list = tmp_list;
  1333. }
  1334. local_list[list_index] = PERM_STRDUP(name);
  1335. if ( local_list[list_index] == NULL ) {
  1336. ACL_NameListDestroy(errp, local_list);
  1337. return(ACLERRNOMEM);
  1338. }
  1339. list_index++;
  1340. local_list[list_index] = NULL;
  1341. }
  1342. *name_list = local_list;
  1343. return(0);
  1344. }
  1345. /*
  1346. * Changes method to method plus DBTYPE, and registers
  1347. * databases.
  1348. *
  1349. * Input:
  1350. * errp error stack
  1351. * acl_list Target ACL list handle
  1352. * Returns:
  1353. * 0 success
  1354. * < 0 failure
  1355. */
  1356. NSAPI_PUBLIC int
  1357. ACL_ListPostParseForAuth(NSErr_t *errp, ACLListHandle_t *acl_list )
  1358. {
  1359. ACLHandle_t *acl;
  1360. ACLWrapper_t *wrap;
  1361. ACLExprHandle_t *expr;
  1362. char *method;
  1363. char *database;
  1364. int rv;
  1365. ACLDbType_t *dbtype;
  1366. ACLMethod_t *methodtype;
  1367. if ( acl_list == NULL )
  1368. return(0);
  1369. for ( wrap = acl_list->acl_list_head; wrap; wrap = wrap->wrap_next ) {
  1370. acl = wrap->acl;
  1371. if ( acl == NULL )
  1372. continue;
  1373. for ( expr = acl->expr_list_head; expr; expr = expr->expr_next ) {
  1374. if ( expr->expr_type != ACL_EXPR_TYPE_AUTH ||
  1375. expr->expr_auth == NULL)
  1376. continue;
  1377. rv = PListGetValue(expr->expr_auth, ACL_ATTR_METHOD_INDEX,
  1378. (void **) &method, NULL);
  1379. if ( rv >= 0 ) {
  1380. methodtype = (ACLMethod_t *)PERM_MALLOC(sizeof(ACLMethod_t));
  1381. rv = ACL_MethodFind(errp, method, methodtype);
  1382. if (rv) {
  1383. nserrGenerate(errp, ACLERRUNDEF, ACLERR3800, ACL_Program,
  1384. 3, acl->tag, "method", method);
  1385. PERM_FREE(methodtype);
  1386. return(ACLERRUNDEF);
  1387. }
  1388. rv = PListSetValue(expr->expr_auth, ACL_ATTR_METHOD_INDEX,
  1389. methodtype, NULL);
  1390. if ( rv < 0 ) {
  1391. nserrGenerate(errp, ACLERRNOMEM, ACLERR3810, ACL_Program,
  1392. 0);
  1393. return(ACLERRNOMEM);
  1394. }
  1395. PERM_FREE(method);
  1396. }
  1397. rv = PListGetValue(expr->expr_auth, ACL_ATTR_DATABASE_INDEX,
  1398. (void **) &database, NULL);
  1399. if (rv < 0) continue;
  1400. /* The following function lets user use databases which are
  1401. * not registered by their administrators. This also fixes
  1402. * the backward compatibility.
  1403. */
  1404. dbtype = (ACLDbType_t *)PERM_MALLOC(sizeof(ACLDbType_t));
  1405. rv = ACL_RegisterDbFromACL(errp, (const char *) database,
  1406. dbtype);
  1407. if (rv < 0) {
  1408. nserrGenerate(errp, ACLERRUNDEF, ACLERR3800, ACL_Program,
  1409. 3, acl->tag, "database", database);
  1410. PERM_FREE(dbtype);
  1411. return(ACLERRUNDEF);
  1412. }
  1413. rv = PListInitProp(expr->expr_auth, ACL_ATTR_DBTYPE_INDEX, ACL_ATTR_DBTYPE,
  1414. dbtype, NULL);
  1415. if ( rv < 0 ) {
  1416. nserrGenerate(errp, ACLERRNOMEM, ACLERR3810, ACL_Program,
  1417. 0);
  1418. return(ACLERRNOMEM);
  1419. }
  1420. }
  1421. }
  1422. return(0);
  1423. }
  1424. /*
  1425. * The following routines are used to validate input parameters. They always
  1426. * return 1, or cause an PR_ASSERT failure. The proper way to use them is
  1427. * with an PR_ASSERT in the calling function. E.g.
  1428. * PR_ASSERT(ACL_AssertAcllist(acllist));
  1429. */
  1430. int
  1431. ACL_AssertAcllist(ACLListHandle_t *acllist)
  1432. {
  1433. ACLWrapper_t *wrap;
  1434. if (acllist == ACL_LIST_NO_ACLS) return 1;
  1435. PR_ASSERT(acllist);
  1436. PR_ASSERT(acllist->acl_list_head);
  1437. PR_ASSERT(acllist->acl_list_tail);
  1438. PR_ASSERT(acllist->acl_count);
  1439. PR_ASSERT(acllist->ref_count > 0);
  1440. for (wrap=acllist->acl_list_head; wrap; wrap=wrap->wrap_next) {
  1441. PR_ASSERT(ACL_AssertAcl(wrap->acl));
  1442. }
  1443. /* Artificially limit ACL lists to 10 ACLs for now */
  1444. PR_ASSERT(acllist->acl_count < 10);
  1445. return 1;
  1446. }
  1447. int
  1448. ACL_AssertAcl(ACLHandle_t *acl)
  1449. {
  1450. PR_ASSERT(acl);
  1451. PR_ASSERT(acl->ref_count);
  1452. PR_ASSERT(acl->expr_count);
  1453. PR_ASSERT(acl->expr_list_head);
  1454. PR_ASSERT(acl->expr_list_tail);
  1455. return 1;
  1456. }
  1457. static PList_t ACLAttr2IndexPList = NULL;
  1458. int
  1459. ACL_InitAttr2Index(void)
  1460. {
  1461. intptr_t i;
  1462. if (ACLAttr2IndexPList) return 0;
  1463. ACLAttr2IndexPList = PListNew(NULL);
  1464. for (i = 1; i < ACL_ATTR_INDEX_MAX; i++) {
  1465. PListInitProp(ACLAttr2IndexPList, 0, ACLAttrTable[i], (const void *)i, NULL);
  1466. }
  1467. return 0;
  1468. }
  1469. /*
  1470. * Attempt to locate the index number for one of the known attribute names
  1471. * that are stored in plists. If we can't match it, just return 0.
  1472. */
  1473. int
  1474. ACL_Attr2Index(const char *attrname)
  1475. {
  1476. int index = 0;
  1477. if ( ACLAttr2IndexPList ) {
  1478. PListFindValue(ACLAttr2IndexPList, attrname, (void **)&index, NULL);
  1479. if (index < 0) index = 0;
  1480. }
  1481. return index;
  1482. }
  1483. void
  1484. ACL_Attr2IndexListDestroy(void)
  1485. {
  1486. PListDestroy(ACLAttr2IndexPList);
  1487. if(acl_parse_crit)
  1488. crit_terminate(acl_parse_crit);
  1489. acl_free_buffer();
  1490. }