acltools.cpp 41 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749
  1. /** BEGIN COPYRIGHT BLOCK
  2. * Copyright (C) 2001 Sun Microsystems, Inc. Used by permission.
  3. * Copyright (C) 2005 Red Hat, Inc.
  4. * All rights reserved.
  5. *
  6. * License: GPL (version 3 or any later version).
  7. * See LICENSE for details.
  8. * END COPYRIGHT BLOCK **/
  9. #ifdef HAVE_CONFIG_H
  10. # include <config.h>
  11. #endif
  12. /*
  13. * Tools to build and maintain access control lists.
  14. */
  15. #include <stdio.h>
  16. #include <string.h>
  17. #define ALLOCATE_ATTR_TABLE 1 /* Include the table of PList names */
  18. #include <netsite.h>
  19. #include <base/plist.h>
  20. #include <base/util.h>
  21. #include <base/crit.h>
  22. #include <base/file.h>
  23. #include <libaccess/acl.h>
  24. #include "aclpriv.h"
  25. #include <libaccess/aclproto.h>
  26. #include <libaccess/aclerror.h>
  27. #include <libaccess/symbols.h>
  28. #include <libaccess/aclstruct.h>
  29. #include <libaccess/las.h>
  30. #include "aclscan.h"
  31. #include "parse.h"
  32. #include "oneeval.h"
  33. #include <libaccess/authdb.h>
  34. static CRITICAL acl_parse_crit = NULL;
  35. /*
  36. * Allocate a new ACL handle
  37. *
  38. * This function creates a new ACL structure that will be used for
  39. * access control information.
  40. *
  41. * Input:
  42. * tag Specifies an identifier name for the new ACL, or
  43. * it may be NULL when no name is required.
  44. * Returns:
  45. * A new ACL structure.
  46. */
  47. NSAPI_PUBLIC ACLHandle_t *
  48. ACL_AclNew(NSErr_t *errp, char *tag )
  49. {
  50. ACLHandle_t *handle;
  51. handle = ( ACLHandle_t * ) PERM_CALLOC ( 1 * sizeof (ACLHandle_t) );
  52. if ( handle && tag ) {
  53. handle->tag = PERM_STRDUP( tag );
  54. if ( handle->tag == NULL ) {
  55. PERM_FREE(handle);
  56. return(NULL);
  57. }
  58. }
  59. return(handle);
  60. }
  61. /*
  62. * Appends to a specified ACL
  63. *
  64. * This function appends a specified ACL to the end of a given ACL list.
  65. *
  66. * Input:
  67. * errp The error stack
  68. * flags should always be zero now
  69. * acl_list target ACL list
  70. * acl new acl
  71. * Returns:
  72. * < 0 failure
  73. * > 0 The number of acl's in the current list
  74. */
  75. NSAPI_PUBLIC int
  76. ACL_ExprAppend( NSErr_t *errp, ACLHandle_t *acl,
  77. ACLExprHandle_t *expr )
  78. {
  79. if ( acl == NULL || expr == NULL )
  80. return(ACLERRUNDEF);
  81. expr->acl_tag = acl->tag;
  82. if ( expr->expr_type == ACL_EXPR_TYPE_AUTH ||
  83. expr->expr_type == ACL_EXPR_TYPE_RESPONSE ) {
  84. expr->expr_number = -1; // expr number isn't valid
  85. } else {
  86. acl->expr_count++;
  87. expr->expr_number = acl->expr_count;
  88. }
  89. if ( acl->expr_list_head == NULL ) {
  90. acl->expr_list_head = expr;
  91. acl->expr_list_tail = expr;
  92. } else {
  93. acl->expr_list_tail->expr_next = expr;
  94. acl->expr_list_tail = expr;
  95. }
  96. return(acl->expr_count);
  97. }
  98. /*
  99. * Add authentication information to an ACL
  100. *
  101. * This function adds authentication data to an expr, based on
  102. * the information provided by the parameters.
  103. *
  104. * Input:
  105. * expr an authenticate expression to add database
  106. * and method information to. ie, auth_info
  107. * auth_info authentication information, eg database,
  108. * method, etc.
  109. * Returns:
  110. * 0 success
  111. * < 0 failure
  112. */
  113. NSAPI_PUBLIC int
  114. ACL_ExprAddAuthInfo( ACLExprHandle_t *expr, PList_t auth_info )
  115. {
  116. if ( expr == NULL || auth_info == NULL )
  117. return(ACLERRUNDEF);
  118. expr->expr_auth = auth_info;
  119. return(0);
  120. }
  121. /*
  122. * Add authorization information to an ACL
  123. *
  124. * This function adds an authorization to a given ACL, based on the information
  125. * provided by the parameters.
  126. *
  127. * Input:
  128. * errp The error stack
  129. * access_rights strings which identify the access rights to be
  130. * controlled by the generated expr.
  131. * flags processing flags
  132. * allow non-zero to allow the indicated rights, or zero to
  133. * deny them.
  134. * attr_expr handle for an attribute expression, which may be
  135. * obtained by calling ACL_ExprNew()
  136. * Returns:
  137. * 0 success
  138. * < 0 failure
  139. */
  140. NSAPI_PUBLIC int
  141. ACL_AddPermInfo( NSErr_t *errp, ACLHandle_t *acl,
  142. char **access_rights,
  143. PFlags_t flags,
  144. int allow,
  145. ACLExprHandle_t *expr,
  146. char *tag )
  147. {
  148. if ( acl == NULL || expr == NULL )
  149. return(ACLERRUNDEF);
  150. expr->expr_flags = flags;
  151. expr->expr_argv = (char **) access_rights;
  152. expr->expr_tag = PERM_STRDUP( tag );
  153. if ( expr->expr_tag == NULL )
  154. return(ACLERRNOMEM);
  155. return(ACL_ExprAppend( errp, acl, expr ));
  156. }
  157. /*
  158. * Add rights information to an expression
  159. *
  160. * This function adds a right to an authorization, based on the information
  161. * provided by the parameters.
  162. *
  163. * Input:
  164. * errp The error stack
  165. * access_right strings which identify the access rights to be
  166. * controlled by the generated expr.
  167. * expr handle for an attribute expression, which may be
  168. * obtained by calling ACL_ExprNew()
  169. * Returns:
  170. * 0 success
  171. * < 0 failure
  172. */
  173. NSAPI_PUBLIC int
  174. ACL_ExprAddArg( NSErr_t *errp,
  175. ACLExprHandle_t *expr,
  176. const char *arg )
  177. {
  178. if ( expr == NULL )
  179. return(ACLERRUNDEF);
  180. if (expr->expr_argv == NULL)
  181. expr->expr_argv = (char **) PERM_MALLOC( 2 * sizeof(char *) );
  182. else
  183. expr->expr_argv = (char **) PERM_REALLOC( expr->expr_argv,
  184. (expr->expr_argc+2)
  185. * sizeof(char *) );
  186. if (expr->expr_argv == NULL)
  187. return(ACLERRNOMEM);
  188. expr->expr_argv[expr->expr_argc] = PERM_STRDUP( arg );
  189. if (expr->expr_argv[expr->expr_argc] == NULL)
  190. return(ACLERRNOMEM);
  191. expr->expr_argc++;
  192. expr->expr_argv[expr->expr_argc] = NULL;
  193. return(0);
  194. }
  195. NSAPI_PUBLIC int
  196. ACL_ExprSetDenyWith( NSErr_t *errp, ACLExprHandle_t *expr, char *deny_type, char *deny_response)
  197. {
  198. int rv;
  199. if ( expr->expr_argc == 0 ) {
  200. if ( (rv = ACL_ExprAddArg(errp, expr, deny_type)) < 0 )
  201. return(rv);
  202. if ( (rv = ACL_ExprAddArg(errp, expr, deny_response)) < 0 )
  203. return(rv);
  204. } else if ( expr->expr_argc == 2 ) {
  205. if ( deny_type ) {
  206. if ( expr->expr_argv[0] )
  207. PERM_FREE(expr->expr_argv[0]);
  208. expr->expr_argv[0] = PERM_STRDUP(deny_type);
  209. if ( expr->expr_argv[0] == NULL )
  210. return(ACLERRNOMEM);
  211. }
  212. if ( deny_response ) {
  213. if ( expr->expr_argv[1] )
  214. PERM_FREE(expr->expr_argv[1]);
  215. expr->expr_argv[1] = PERM_STRDUP(deny_response);
  216. if ( expr->expr_argv[0] == NULL )
  217. return(ACLERRNOMEM);
  218. }
  219. } else {
  220. return(ACLERRINTERNAL);
  221. }
  222. return(0);
  223. }
  224. NSAPI_PUBLIC int
  225. ACL_ExprGetDenyWith( NSErr_t *errp, ACLExprHandle_t *expr, char **deny_type,
  226. char **deny_response)
  227. {
  228. if ( expr->expr_argc == 2 ) {
  229. *deny_type = expr->expr_argv[0];
  230. *deny_response = expr->expr_argv[1];
  231. return(0);
  232. } else {
  233. return(ACLERRUNDEF);
  234. }
  235. }
  236. /*
  237. * Function to set the authorization statement processing flags.
  238. *
  239. * Input:
  240. * errp The error reporting stack
  241. * expr The authoization statement
  242. * flags The flags to set
  243. * Returns:
  244. * 0 success
  245. * < 0 failure
  246. */
  247. NSAPI_PUBLIC int
  248. ACL_ExprSetPFlags( NSErr_t *errp,
  249. ACLExprHandle_t *expr,
  250. PFlags_t flags )
  251. {
  252. if ( expr == NULL )
  253. return(ACLERRUNDEF);
  254. expr->expr_flags |= flags;
  255. return(0);
  256. }
  257. /*
  258. * Function to clear the authorization statement processing flags.
  259. *
  260. * Input:
  261. * errp The error reporting stack
  262. * expr The authoization statement
  263. * Returns:
  264. * 0 success
  265. * < 0 failure
  266. */
  267. NSAPI_PUBLIC int
  268. ACL_ExprClearPFlags( NSErr_t *errp,
  269. ACLExprHandle_t *expr )
  270. {
  271. if ( expr == NULL )
  272. return(ACLERRUNDEF);
  273. expr->expr_flags = 0;
  274. return(0);
  275. }
  276. /*
  277. * Allocate a new expression handle.
  278. *
  279. * Returns:
  280. * NULL If handle could not be allocated.
  281. * pointer New handle.
  282. */
  283. NSAPI_PUBLIC ACLExprHandle_t *
  284. ACL_ExprNew( const ACLExprType_t expr_type )
  285. {
  286. ACLExprHandle_t *expr_handle;
  287. expr_handle = ( ACLExprHandle_t * ) PERM_CALLOC ( sizeof(ACLExprHandle_t) );
  288. if ( expr_handle ) {
  289. expr_handle->expr_arry = ( ACLExprEntry_t * )
  290. PERM_CALLOC( ACL_TERM_BSIZE * sizeof(ACLExprEntry_t) ) ;
  291. expr_handle->expr_arry_size = ACL_TERM_BSIZE;
  292. expr_handle->expr_type = expr_type;
  293. expr_handle->expr_raw = ( ACLExprRaw_t * )
  294. PERM_CALLOC( ACL_TERM_BSIZE * sizeof(ACLExprRaw_t) ) ;
  295. expr_handle->expr_raw_size = ACL_TERM_BSIZE;
  296. }
  297. return(expr_handle);
  298. }
  299. /*
  300. * LOCAL FUNCTION
  301. *
  302. * displays the ASCII equivalent index value.
  303. */
  304. static char *
  305. acl_index_string ( int value, char *buffer )
  306. {
  307. if ( value == ACL_TRUE_IDX ) {
  308. strcpy( buffer, "TRUE" );
  309. return( buffer );
  310. }
  311. if ( value == ACL_FALSE_IDX ) {
  312. strcpy( buffer, "FALSE" );
  313. return( buffer );
  314. }
  315. sprintf( buffer, "goto %d", value );
  316. return( buffer );
  317. }
  318. /*
  319. * LOCAL FUNCTION
  320. *
  321. * displays ASCII equivalent of CmpOp_t
  322. */
  323. static const char *
  324. acl_comp_string( CmpOp_t cmp )
  325. {
  326. switch (cmp) {
  327. case CMP_OP_EQ:
  328. return("=");
  329. case CMP_OP_NE:
  330. return("!=");
  331. case CMP_OP_GT:
  332. return(">");
  333. case CMP_OP_LT:
  334. return("<");
  335. case CMP_OP_GE:
  336. return(">=");
  337. case CMP_OP_LE:
  338. return("<=");
  339. default:
  340. return("unknown op");
  341. }
  342. }
  343. /*
  344. * Add a term to the specified attribute expression.
  345. *
  346. * Input:
  347. * errp Error stack
  348. * acl_expr Target expression handle
  349. * attr_name Term Attribute name
  350. * cmp Comparison operator
  351. * attr_pattern Pattern for comparison
  352. * Output:
  353. * acl_expr New term added
  354. * Returns:
  355. * 0 Success
  356. * < 0 Error
  357. */
  358. NSAPI_PUBLIC int
  359. ACL_ExprTerm( NSErr_t *errp, ACLExprHandle_t *acl_expr,
  360. const char *attr_name,
  361. CmpOp_t cmp,
  362. char *attr_pattern )
  363. {
  364. ACLExprEntry_t *expr;
  365. ACLExprRaw_t *raw_expr;
  366. if ( acl_expr == NULL || acl_expr->expr_arry == NULL )
  367. return(ACLERRUNDEF);
  368. if ( acl_expr->expr_term_index >= acl_expr->expr_arry_size ) {
  369. acl_expr->expr_arry = ( ACLExprEntry_t *)
  370. PERM_REALLOC ( acl_expr->expr_arry,
  371. (acl_expr->expr_arry_size + ACL_TERM_BSIZE)
  372. * sizeof(ACLExprEntry_t));
  373. if ( acl_expr->expr_arry == NULL )
  374. return(ACLERRNOMEM);
  375. acl_expr->expr_arry_size += ACL_TERM_BSIZE;
  376. }
  377. expr = &acl_expr->expr_arry[acl_expr->expr_term_index];
  378. acl_expr->expr_term_index++;
  379. expr->attr_name = PERM_STRDUP(attr_name);
  380. if ( expr->attr_name == NULL )
  381. return(ACLERRNOMEM);
  382. expr->comparator = cmp;
  383. expr->attr_pattern = PERM_STRDUP(attr_pattern);
  384. if ( expr->attr_pattern == NULL )
  385. return(ACLERRNOMEM);
  386. expr->true_idx = ACL_TRUE_IDX;
  387. expr->false_idx = ACL_FALSE_IDX;
  388. expr->start_flag = 1;
  389. expr->las_cookie = 0;
  390. expr->las_eval_func = 0;
  391. if ( acl_expr->expr_raw_index >= acl_expr->expr_raw_size ) {
  392. acl_expr->expr_raw = ( ACLExprRaw_t *)
  393. PERM_REALLOC ( acl_expr->expr_raw,
  394. (acl_expr->expr_raw_size + ACL_TERM_BSIZE)
  395. * sizeof(ACLExprRaw_t));
  396. if ( acl_expr->expr_raw == NULL )
  397. return(ACLERRNOMEM);
  398. acl_expr->expr_raw_size += ACL_TERM_BSIZE;
  399. }
  400. raw_expr = &acl_expr->expr_raw[acl_expr->expr_raw_index];
  401. acl_expr->expr_raw_index++;
  402. raw_expr->attr_name = expr->attr_name;
  403. raw_expr->comparator = cmp;
  404. raw_expr->attr_pattern = expr->attr_pattern;
  405. raw_expr->logical = (ACLExprOp_t)0;
  406. #ifdef DEBUG_LEVEL_2
  407. printf ( "%d: %s %s %s, t=%d, f=%d\n",
  408. acl_expr->expr_term_index - 1,
  409. expr->attr_name,
  410. acl_comp_string( expr->comparator ),
  411. expr->attr_pattern,
  412. expr->true_idx,
  413. expr->false_idx );
  414. #endif
  415. return(0);
  416. }
  417. /*
  418. * Negate the previous term or subexpression.
  419. *
  420. * Input:
  421. * errp The error stack
  422. * acl_expr The expression to negate
  423. * Output
  424. * acl_expr The negated expression
  425. * Returns:
  426. * 0 Success
  427. * < 0 Failure
  428. */
  429. NSAPI_PUBLIC int
  430. ACL_ExprNot( NSErr_t *errp, ACLExprHandle_t *acl_expr )
  431. {
  432. int idx;
  433. int ii;
  434. int expr_one = 0;
  435. ACLExprRaw_t *raw_expr;
  436. if ( acl_expr == NULL )
  437. return(ACLERRUNDEF);
  438. if ( acl_expr->expr_raw_index >= acl_expr->expr_raw_size ) {
  439. acl_expr->expr_raw = ( ACLExprRaw_t *)
  440. PERM_REALLOC ( acl_expr->expr_raw,
  441. (acl_expr->expr_raw_size + ACL_TERM_BSIZE)
  442. * sizeof(ACLExprRaw_t));
  443. if ( acl_expr->expr_raw == NULL )
  444. return(ACLERRNOMEM);
  445. acl_expr->expr_raw_size += ACL_TERM_BSIZE;
  446. }
  447. raw_expr = &acl_expr->expr_raw[acl_expr->expr_raw_index];
  448. acl_expr->expr_raw_index++;
  449. raw_expr->logical = ACL_EXPR_OP_NOT;
  450. raw_expr->attr_name = NULL;
  451. /* Find the last expression */
  452. idx = acl_expr->expr_term_index - 1;
  453. for ( ii = idx; ii >= 0; ii-- ) {
  454. if ( acl_expr->expr_arry[ii].start_flag ) {
  455. expr_one = ii;
  456. break;
  457. }
  458. }
  459. #ifdef DEBUG_LEVEL_2
  460. printf("not, start index=%d\n", expr_one);
  461. #endif
  462. /*
  463. * The intent here is negate the last expression by
  464. * modifying the true and false links.
  465. */
  466. for ( ii = expr_one; ii < acl_expr->expr_term_index; ii++ ) {
  467. if ( acl_expr->expr_arry[ii].true_idx == ACL_TRUE_IDX )
  468. acl_expr->expr_arry[ii].true_idx = ACL_FALSE_IDX;
  469. else if ( acl_expr->expr_arry[ii].true_idx == ACL_FALSE_IDX )
  470. acl_expr->expr_arry[ii].true_idx = ACL_TRUE_IDX;
  471. if ( acl_expr->expr_arry[ii].false_idx == ACL_TRUE_IDX )
  472. acl_expr->expr_arry[ii].false_idx = ACL_FALSE_IDX;
  473. else if ( acl_expr->expr_arry[ii].false_idx == ACL_FALSE_IDX )
  474. acl_expr->expr_arry[ii].false_idx = ACL_TRUE_IDX;
  475. }
  476. return(0) ;
  477. }
  478. /*
  479. * Logical 'and' the previous two terms or subexpressions.
  480. *
  481. * Input:
  482. * errp The error stack
  483. * acl_expr The terms or subexpressions
  484. * Output:
  485. * acl_expr The expression after logical 'and'
  486. */
  487. NSAPI_PUBLIC int
  488. ACL_ExprAnd( NSErr_t *errp, ACLExprHandle_t *acl_expr )
  489. {
  490. int idx;
  491. int ii;
  492. int expr_one = ACL_FALSE_IDX;
  493. int expr_two = ACL_FALSE_IDX;
  494. ACLExprRaw_t *raw_expr;
  495. if ( acl_expr == NULL )
  496. return(ACLERRUNDEF);
  497. if ( acl_expr->expr_raw_index >= acl_expr->expr_raw_size ) {
  498. acl_expr->expr_raw = ( ACLExprRaw_t *)
  499. PERM_REALLOC ( acl_expr->expr_raw,
  500. (acl_expr->expr_raw_size + ACL_TERM_BSIZE)
  501. * sizeof(ACLExprRaw_t) );
  502. if ( acl_expr->expr_raw == NULL )
  503. return(ACLERRNOMEM);
  504. acl_expr->expr_raw_size += ACL_TERM_BSIZE;
  505. }
  506. raw_expr = &acl_expr->expr_raw[acl_expr->expr_raw_index];
  507. acl_expr->expr_raw_index++;
  508. raw_expr->logical = ACL_EXPR_OP_AND;
  509. raw_expr->attr_name = NULL;
  510. /* Find the last two expressions */
  511. idx = acl_expr->expr_term_index - 1;
  512. for ( ii = idx; ii >= 0; ii-- ) {
  513. if ( acl_expr->expr_arry[ii].start_flag ) {
  514. if ( expr_two == ACL_FALSE_IDX )
  515. expr_two = ii;
  516. else if ( expr_one == ACL_FALSE_IDX ) {
  517. expr_one = ii;
  518. break;
  519. }
  520. }
  521. }
  522. #ifdef DEBUG_LEVEL_2
  523. printf("and, index=%d, first expr=%d, second expr=%d\n", idx, expr_one, expr_two);
  524. #endif
  525. for ( ii = expr_one; ii < expr_two; ii++) {
  526. if ( acl_expr->expr_arry[ii].true_idx == ACL_TRUE_IDX )
  527. acl_expr->expr_arry[ii].true_idx = expr_two;
  528. if ( acl_expr->expr_arry[ii].false_idx == ACL_TRUE_IDX )
  529. acl_expr->expr_arry[ii].false_idx = expr_two;
  530. }
  531. acl_expr->expr_arry[expr_two].start_flag = 0;
  532. return(0);
  533. }
  534. /*
  535. * Logical 'or' the previous two terms or subexpressions.
  536. *
  537. * Input:
  538. * errp The error stack
  539. * acl_expr The terms or subexpressions
  540. * Output:
  541. * acl_expr The expression after logical 'or'
  542. */
  543. NSAPI_PUBLIC int
  544. ACL_ExprOr( NSErr_t *errp, ACLExprHandle_t *acl_expr )
  545. {
  546. int idx;
  547. int ii;
  548. int expr_one = ACL_FALSE_IDX;
  549. int expr_two = ACL_FALSE_IDX;
  550. ACLExprRaw_t *raw_expr;
  551. if ( acl_expr == NULL )
  552. return(ACLERRUNDEF);
  553. if ( acl_expr->expr_raw_index >= acl_expr->expr_raw_size ) {
  554. acl_expr->expr_raw = ( ACLExprRaw_t *)
  555. PERM_REALLOC ( acl_expr->expr_raw,
  556. (acl_expr->expr_raw_size + ACL_TERM_BSIZE)
  557. * sizeof(ACLExprRaw_t) );
  558. if ( acl_expr->expr_raw == NULL )
  559. return(ACLERRNOMEM);
  560. acl_expr->expr_raw_size += ACL_TERM_BSIZE;
  561. }
  562. raw_expr = &acl_expr->expr_raw[acl_expr->expr_raw_index];
  563. acl_expr->expr_raw_index++;
  564. raw_expr->logical = ACL_EXPR_OP_OR;
  565. raw_expr->attr_name = NULL;
  566. /* Find the last two expressions */
  567. idx = acl_expr->expr_term_index - 1;
  568. for ( ii = idx; ii >= 0; ii-- ) {
  569. if ( acl_expr->expr_arry[ii].start_flag ) {
  570. if ( expr_two == ACL_FALSE_IDX )
  571. expr_two = ii;
  572. else if ( expr_one == ACL_FALSE_IDX ) {
  573. expr_one = ii;
  574. break;
  575. }
  576. }
  577. }
  578. #ifdef DEBUG_LEVEL_2
  579. printf("or, index=%d, first expr=%d, second expr=%d\n", idx, expr_one, expr_two);
  580. #endif
  581. for ( ii = expr_one; ii < expr_two; ii++) {
  582. if ( acl_expr->expr_arry[ii].true_idx == ACL_FALSE_IDX )
  583. acl_expr->expr_arry[ii].true_idx = expr_two;
  584. if ( acl_expr->expr_arry[ii].false_idx == ACL_FALSE_IDX )
  585. acl_expr->expr_arry[ii].false_idx = expr_two;
  586. }
  587. acl_expr->expr_arry[expr_two].start_flag = 0;
  588. return(0);
  589. }
  590. /*
  591. * INTERNAL FUNCTION (GLOBAL)
  592. *
  593. * Write an expression array to standard output. This
  594. * is only useful debugging.
  595. */
  596. int
  597. ACL_ExprDisplay( ACLExprHandle_t *acl_expr )
  598. {
  599. int ii;
  600. char buffer[256];
  601. if ( acl_expr == NULL )
  602. return(0);
  603. for ( ii = 0; ii < acl_expr->expr_term_index; ii++ ) {
  604. printf ("%d: if ( %s %s %s ) ",
  605. ii,
  606. acl_expr->expr_arry[ii].attr_name,
  607. acl_comp_string( acl_expr->expr_arry[ii].comparator ),
  608. acl_expr->expr_arry[ii].attr_pattern );
  609. printf("%s ", acl_index_string(acl_expr->expr_arry[ii].true_idx, buffer));
  610. printf("else %s\n",
  611. acl_index_string(acl_expr->expr_arry[ii].false_idx, buffer) );
  612. }
  613. return(0);
  614. }
  615. /*
  616. * Creates a handle for a new list of ACLs
  617. *
  618. * This function creates a new list of ACLs. The list is initially empty
  619. * and can be added to by ACL_ListAppend(). A resource manager would use
  620. * these functions to build up a list of all the ACLs applicable to a
  621. * particular resource access.
  622. *
  623. * Input:
  624. * Returns:
  625. * NULL failure, otherwise returns a new
  626. * ACLListHandle
  627. */
  628. NSAPI_PUBLIC ACLListHandle_t *
  629. ACL_ListNew(NSErr_t *errp)
  630. {
  631. ACLListHandle_t *handle;
  632. handle = ( ACLListHandle_t * ) PERM_CALLOC ( sizeof(ACLListHandle_t) );
  633. handle->ref_count = 1;
  634. return(handle);
  635. }
  636. /*
  637. * Allocates a handle for an ACL wrapper
  638. *
  639. * This wrapper is just used for ACL list creation. It's a way of
  640. * linking ACLs into a list. This is an internal function.
  641. */
  642. static ACLWrapper_t *
  643. acl_wrapper_new(void)
  644. {
  645. ACLWrapper_t *handle;
  646. handle = ( ACLWrapper_t * ) PERM_CALLOC ( sizeof(ACLWrapper_t) );
  647. return(handle);
  648. }
  649. /*
  650. * Description
  651. *
  652. * This function destroys an entry a symbol table entry for an
  653. * ACL.
  654. *
  655. * Arguments:
  656. *
  657. * sym - pointer to Symbol_t for an ACL entry
  658. * argp - unused (must be zero)
  659. *
  660. * Returns:
  661. *
  662. * The return value is SYMENUMREMOVE.
  663. */
  664. static
  665. int acl_hash_entry_destroy(Symbol_t * sym, void * argp)
  666. {
  667. if (sym != 0) {
  668. /* Free the acl name string if any */
  669. if (sym->sym_name != 0) {
  670. PERM_FREE(sym->sym_name);
  671. }
  672. /* Free the Symbol_t structure */
  673. PERM_FREE(sym);
  674. }
  675. /* Indicate that the symbol table entry should be removed */
  676. return SYMENUMREMOVE;
  677. }
  678. /*
  679. * LOCAL FUNCTION
  680. *
  681. * Create a new symbol with the sym_name equal to the
  682. * acl->tag value. Attaches the acl to the sym_data
  683. * pointer.
  684. */
  685. static Symbol_t *
  686. acl_sym_new(ACLHandle_t *acl)
  687. {
  688. Symbol_t *sym;
  689. /* It's not there, so add it */
  690. sym = (Symbol_t *) PERM_MALLOC(sizeof(Symbol_t));
  691. if ( sym == NULL )
  692. return(NULL);
  693. sym->sym_name = PERM_STRDUP(acl->tag);
  694. if ( sym->sym_name == NULL ) {
  695. PERM_FREE(sym);
  696. return(NULL);
  697. }
  698. sym->sym_type = ACLSYMACL;
  699. sym->sym_data = (void *) acl;
  700. return(sym);
  701. }
  702. /*
  703. * LOCAL FUNCTION
  704. *
  705. * Add a acl symbol to an acl_list's symbol table.
  706. *
  707. * Each acl list has a symbol table. the symbol table
  708. * is a quick qay to reference named acl's
  709. */
  710. static int
  711. acl_sym_add(ACLListHandle_t *acl_list, ACLHandle_t *acl)
  712. {
  713. Symbol_t *sym;
  714. int rv;
  715. if ( acl->tag == NULL )
  716. return(ACLERRUNDEF);
  717. rv = symTableFindSym(acl_list->acl_sym_table,
  718. acl->tag,
  719. ACLSYMACL,
  720. (void **)&sym);
  721. if ( rv == SYMERRNOSYM ) {
  722. sym = acl_sym_new(acl);
  723. if ( sym )
  724. rv = symTableAddSym(acl_list->acl_sym_table, sym, (void *)sym);
  725. }
  726. if ( sym == NULL || rv < 0 )
  727. return(ACLERRUNDEF);
  728. return(0);
  729. }
  730. /*
  731. * LOCAL FUNCTION
  732. *
  733. * Destroy an acl_list's symbol table and all memory referenced
  734. * by the symbol table. This does not destroy an acl_list.
  735. */
  736. static void
  737. acl_symtab_destroy(ACLListHandle_t *acl_list)
  738. {
  739. /* Destroy each entry in the symbol table */
  740. symTableEnumerate(acl_list->acl_sym_table, 0, acl_hash_entry_destroy);
  741. /* Destory the hash table itself */
  742. symTableDestroy(acl_list->acl_sym_table, 0);
  743. acl_list->acl_sym_table = NULL;
  744. return;
  745. }
  746. /*
  747. * Appends to a specified ACL
  748. *
  749. * This function appends a specified ACL to the end of a given ACL list.
  750. *
  751. * Input:
  752. * errp The error stack
  753. * flags should always be zero now
  754. * acl_list target ACL list
  755. * acl new acl
  756. * Returns:
  757. * > 0 The number of acl's in the current list
  758. * < 0 failure
  759. */
  760. NSAPI_PUBLIC int
  761. ACL_ListAppend( NSErr_t *errp, ACLListHandle_t *acl_list, ACLHandle_t *acl,
  762. int flags )
  763. {
  764. ACLWrapper_t *wrapper;
  765. ACLHandle_t *tmp_acl;
  766. if ( acl_list == NULL || acl == NULL )
  767. return(ACLERRUNDEF);
  768. if ( acl_list->acl_sym_table == NULL &&
  769. acl_list->acl_count == ACL_TABLE_THRESHOLD ) {
  770. /*
  771. * The symbol table isn't really critical so we don't log
  772. * an error if its creation fails.
  773. */
  774. symTableNew(&acl_list->acl_sym_table);
  775. if ( acl_list->acl_sym_table ) {
  776. for (wrapper = acl_list->acl_list_head; wrapper;
  777. wrapper = wrapper->wrap_next ) {
  778. tmp_acl = wrapper->acl;
  779. if ( acl_sym_add(acl_list, tmp_acl) ) {
  780. acl_symtab_destroy(acl_list);
  781. break;
  782. }
  783. }
  784. }
  785. }
  786. wrapper = acl_wrapper_new();
  787. if ( wrapper == NULL )
  788. return(ACLERRNOMEM);
  789. wrapper->acl = acl;
  790. if ( acl_list->acl_list_head == NULL ) {
  791. acl_list->acl_list_head = wrapper;
  792. acl_list->acl_list_tail = wrapper;
  793. } else {
  794. acl_list->acl_list_tail->wrap_next = wrapper;
  795. acl_list->acl_list_tail = wrapper;
  796. }
  797. acl->ref_count++;
  798. acl_list->acl_count++;
  799. if ( acl_list->acl_sym_table ) {
  800. /*
  801. * If we fail to insert the ACL then we
  802. * might as well destroy this hash table since it is
  803. * useless.
  804. */
  805. if ( acl_sym_add(acl_list, acl) ) {
  806. acl_symtab_destroy(acl_list);
  807. }
  808. }
  809. return(acl_list->acl_count);
  810. }
  811. /*
  812. * Concatenates two ACL lists
  813. *
  814. * Attaches all ACLs in acl_list2 to the end of acl_list1. acl_list2
  815. * is left unchanged.
  816. *
  817. * Input:
  818. * errp pointer to the error stack
  819. * acl_list1 target ACL list
  820. * acl_list2 source ACL list
  821. * Output:
  822. * acl_list1 list contains the concatenation of acl_list1
  823. * and acl_list2.
  824. * Returns:
  825. * > 0 Number of ACLs in acl_list1 after concat
  826. * < 0 failure
  827. */
  828. NSAPI_PUBLIC int
  829. ACL_ListConcat( NSErr_t *errp, ACLListHandle_t *acl_list1,
  830. ACLListHandle_t *acl_list2, int flags )
  831. {
  832. ACLWrapper_t *wrapper;
  833. int rv;
  834. if ( acl_list1 == NULL || acl_list2 == NULL )
  835. return(ACLERRUNDEF);
  836. for ( wrapper = acl_list2->acl_list_head;
  837. wrapper != NULL; wrapper = wrapper->wrap_next )
  838. if ( (rv = ACL_ListAppend ( errp, acl_list1, wrapper->acl, 0 )) < 0 )
  839. return(rv);
  840. return(acl_list1->acl_count);
  841. }
  842. /*
  843. * LOCAL FUNCTION
  844. *
  845. * Free up memory associated with and ACLExprEntry. Probably
  846. * only useful internally since we aren't exporting
  847. * this structure.
  848. */
  849. static void
  850. ACL_ExprEntryDestroy( ACLExprEntry_t *entry )
  851. {
  852. LASFlushFunc_t flushp;
  853. if ( entry == NULL )
  854. return;
  855. if ( entry->las_cookie )
  856. /* freeLAS(NULL, entry->attr_name, &entry->las_cookie); */
  857. {
  858. ACL_LasFindFlush( NULL, entry->attr_name, &flushp );
  859. if ( flushp )
  860. ( *flushp )( &entry->las_cookie );
  861. }
  862. if ( entry->attr_name )
  863. PERM_FREE( entry->attr_name );
  864. if ( entry->attr_pattern )
  865. PERM_FREE( entry->attr_pattern );
  866. return;
  867. }
  868. /*
  869. * LOCAL FUNCTION
  870. *
  871. * This function is used to free all the pvalue memory
  872. * in a plist.
  873. */
  874. static void
  875. acl_expr_auth_destroy(char *pname, const void *pvalue, void *user_data)
  876. {
  877. PERM_FREE((char *) pvalue);
  878. return;
  879. }
  880. /*
  881. * Free up memory associated with and ACLExprHandle.
  882. *
  883. * Input:
  884. * expr expression handle to free up
  885. */
  886. NSAPI_PUBLIC void
  887. ACL_ExprDestroy( ACLExprHandle_t *expr )
  888. {
  889. int ii;
  890. if ( expr == NULL )
  891. return;
  892. if ( expr->expr_tag )
  893. PERM_FREE( expr->expr_tag );
  894. if ( expr->expr_argv ) {
  895. for ( ii = 0; ii < expr->expr_argc; ii++ )
  896. if ( expr->expr_argv[ii] )
  897. PERM_FREE( expr->expr_argv[ii] );
  898. PERM_FREE( expr->expr_argv );
  899. }
  900. for ( ii = 0; ii < expr->expr_term_index; ii++ )
  901. ACL_ExprEntryDestroy( &expr->expr_arry[ii] );
  902. if ( expr->expr_auth ) {
  903. PListEnumerate(expr->expr_auth, acl_expr_auth_destroy, NULL);
  904. PListDestroy(expr->expr_auth);
  905. }
  906. PERM_FREE( expr->expr_arry );
  907. PERM_FREE( expr->expr_raw );
  908. PERM_FREE( expr );
  909. return;
  910. }
  911. /*
  912. * Free up memory associated with and ACLHandle.
  913. *
  914. * Input:
  915. * acl target acl
  916. */
  917. NSAPI_PUBLIC void
  918. ACL_AclDestroy(NSErr_t *errp, ACLHandle_t *acl )
  919. {
  920. ACLExprHandle_t *handle;
  921. ACLExprHandle_t *tmp;
  922. if ( acl == NULL )
  923. return;
  924. acl->ref_count--;
  925. if ( acl->ref_count )
  926. return;
  927. if ( acl->tag )
  928. PERM_FREE( acl->tag );
  929. if ( acl->las_name )
  930. PERM_FREE( acl->las_name );
  931. if ( acl->attr_name )
  932. PERM_FREE( acl->attr_name );
  933. handle = acl->expr_list_head;
  934. while ( handle ) {
  935. tmp = handle;
  936. handle = handle->expr_next;
  937. ACL_ExprDestroy( tmp );
  938. }
  939. PERM_FREE(acl);
  940. return;
  941. }
  942. /*
  943. * Destorys a input ACL List
  944. *
  945. * Input:
  946. * acl_list target list
  947. * Output:
  948. * none target list is freed
  949. */
  950. NSAPI_PUBLIC void
  951. ACL_ListDestroy(NSErr_t *errp, ACLListHandle_t *acl_list )
  952. {
  953. ACLWrapper_t *wrapper;
  954. ACLWrapper_t *tmp_wrapper;
  955. ACLHandle_t *tmp_acl;
  956. if ( acl_list == NULL )
  957. return;
  958. if ( acl_list->acl_sym_table ) {
  959. /* Destroy each entry in the symbol table */
  960. symTableEnumerate(acl_list->acl_sym_table, 0, acl_hash_entry_destroy);
  961. /* Destory the hash table itself */
  962. symTableDestroy(acl_list->acl_sym_table, 0);
  963. }
  964. ACL_EvalDestroyContext( (ACLListCache_t *)acl_list->cache );
  965. wrapper = acl_list->acl_list_head;
  966. while ( wrapper ) {
  967. tmp_acl = wrapper->acl;
  968. tmp_wrapper = wrapper;
  969. wrapper = wrapper->wrap_next;
  970. PERM_FREE( tmp_wrapper );
  971. ACL_AclDestroy(errp, tmp_acl );
  972. }
  973. PERM_FREE( acl_list );
  974. return;
  975. }
  976. /*
  977. * FUNCTION: ACL_ListGetFirst
  978. *
  979. * DESCRIPTION:
  980. *
  981. * This function is used to start an enumeration of an
  982. * ACLListHandle_t. It returns an ACLHandle_t* for the first
  983. * ACL on the list, and initializes a handle supplied by the
  984. * caller, which is used to track the current position in the
  985. * enumeration. This function is normally used in a loop
  986. * such as:
  987. *
  988. * ACLListHandle_t *acl_list = <some ACL list>;
  989. * ACLHandle_t *cur_acl;
  990. * ACLListEnum_t acl_enum;
  991. *
  992. * for (cur_acl = ACL_ListGetFirst(acl_list, &acl_enum);
  993. * cur_acl != 0;
  994. * cur_acl = ACL_ListGetNext(acl_list, &acl_enum)) {
  995. * ...
  996. * }
  997. *
  998. * The caller should guarantee that no ACLs are added or removed
  999. * from the ACL list during the enumeration.
  1000. *
  1001. * ARGUMENTS:
  1002. *
  1003. * acl_list - handle for the ACL list
  1004. * acl_enum - pointer to uninitialized enumeration handle
  1005. *
  1006. * RETURNS:
  1007. *
  1008. * As described above. If the acl_list argument is null, or the
  1009. * referenced ACL list is empty, the return value is null.
  1010. */
  1011. NSAPI_PUBLIC ACLHandle_t *
  1012. ACL_ListGetFirst(ACLListHandle_t *acl_list, ACLListEnum_t *acl_enum)
  1013. {
  1014. ACLWrapper_t *wrapper;
  1015. ACLHandle_t *acl = 0;
  1016. *acl_enum = 0;
  1017. if (acl_list) {
  1018. wrapper = acl_list->acl_list_head;
  1019. *acl_enum = (ACLListEnum_t)wrapper;
  1020. if (wrapper) {
  1021. acl = wrapper->acl;
  1022. }
  1023. }
  1024. return acl;
  1025. }
  1026. NSAPI_PUBLIC ACLHandle_t *
  1027. ACL_ListGetNext(ACLListHandle_t *acl_list, ACLListEnum_t *acl_enum)
  1028. {
  1029. ACLWrapper_t *wrapper = (ACLWrapper_t *)(*acl_enum);
  1030. ACLHandle_t *acl = 0;
  1031. if (wrapper) {
  1032. wrapper = wrapper->wrap_next;
  1033. *acl_enum = (ACLListEnum_t)wrapper;
  1034. if (wrapper) acl = wrapper->acl;
  1035. }
  1036. return acl;
  1037. }
  1038. /*
  1039. * FUNCTION: ACL_AclGetTag
  1040. *
  1041. * DESCRIPTION:
  1042. *
  1043. * Returns the tag string associated with an ACL.
  1044. *
  1045. * ARGUMENTS:
  1046. *
  1047. * acl - handle for an ACL
  1048. *
  1049. * RETURNS:
  1050. *
  1051. * The return value is a pointer to the ACL tag string.
  1052. */
  1053. NSAPI_PUBLIC const char *
  1054. ACL_AclGetTag(ACLHandle_t *acl)
  1055. {
  1056. return (acl) ? (const char *)(acl->tag) : 0;
  1057. }
  1058. /*
  1059. * Finds a named ACL in an input list.
  1060. *
  1061. * Input:
  1062. * acl_list a list of ACLs to search
  1063. * acl_name the name of the ACL to find
  1064. * flags e.g. ACL_CASE_INSENSITIVE
  1065. * Returns:
  1066. * NULL No ACL found
  1067. * acl A pointer to an ACL with named acl_name
  1068. */
  1069. NSAPI_PUBLIC ACLHandle_t *
  1070. ACL_ListFind (NSErr_t *errp, ACLListHandle_t *acl_list, char *acl_name, int flags )
  1071. {
  1072. ACLHandle_t *result = NULL;
  1073. ACLWrapper_t *wrapper;
  1074. Symbol_t *sym;
  1075. if ( acl_list == NULL || acl_name == NULL )
  1076. return( result );
  1077. /*
  1078. * right now the symbol table exists if there hasn't been
  1079. * any collisions based on using case insensitive names.
  1080. * if there are any collisions then the table will be
  1081. * deleted and we will look up using list search.
  1082. *
  1083. * we should probably create two hash tables, one for case
  1084. * sensitive lookups and the other for insensitive.
  1085. */
  1086. if ( acl_list->acl_sym_table ) {
  1087. if ( symTableFindSym(acl_list->acl_sym_table,
  1088. acl_name, ACLSYMACL, (void **) &sym) >= 0 ) {
  1089. result = (ACLHandle_t *) sym->sym_data;
  1090. if ( result && (flags & ACL_CASE_SENSITIVE) &&
  1091. strcmp(result->tag, acl_name) ) {
  1092. result = NULL; /* case doesn't match */
  1093. }
  1094. }
  1095. return( result );
  1096. }
  1097. if ( flags & ACL_CASE_INSENSITIVE ) {
  1098. for ( wrapper = acl_list->acl_list_head; wrapper != NULL;
  1099. wrapper = wrapper->wrap_next ) {
  1100. if ( wrapper->acl->tag &&
  1101. strcasecmp( wrapper->acl->tag, acl_name ) == 0 ) {
  1102. result = wrapper->acl;
  1103. break;
  1104. }
  1105. }
  1106. } else {
  1107. for ( wrapper = acl_list->acl_list_head; wrapper != NULL;
  1108. wrapper = wrapper->wrap_next ) {
  1109. if ( wrapper->acl->tag &&
  1110. strcmp( wrapper->acl->tag, acl_name ) == 0 ) {
  1111. result = wrapper->acl;
  1112. break;
  1113. }
  1114. }
  1115. }
  1116. return( result );
  1117. }
  1118. /*
  1119. * Function parses an input ACL string and returns an
  1120. * ACLListHandle_t pointer that represents the entire
  1121. * file without the comments.
  1122. *
  1123. * Input:
  1124. * buffer the target ACL buffer
  1125. * errp a pointer to an error stack
  1126. *
  1127. * Returns:
  1128. * NULL parse failed
  1129. *
  1130. */
  1131. NSAPI_PUBLIC ACLListHandle_t *
  1132. ACL_ParseString( NSErr_t *errp, char *buffer )
  1133. {
  1134. ACLListHandle_t *handle = NULL;
  1135. int eid = 0;
  1136. int rv = 0;
  1137. const char *errmsg;
  1138. ACL_InitAttr2Index();
  1139. if ( acl_parse_crit == NULL )
  1140. acl_parse_crit = crit_init();
  1141. crit_enter( acl_parse_crit );
  1142. if ( acl_InitScanner( errp, NULL, buffer ) < 0 ) {
  1143. rv = ACLERRNOMEM;
  1144. eid = ACLERR1920;
  1145. nserrGenerate(errp, rv, eid, ACL_Program, 0);
  1146. } else {
  1147. handle = ACL_ListNew(errp);
  1148. if ( handle == NULL ) {
  1149. rv = ACLERRNOMEM;
  1150. eid = ACLERR1920;
  1151. nserrGenerate(errp, rv, eid, ACL_Program, 0);
  1152. } else if ( acl_PushListHandle( handle ) < 0 ) {
  1153. rv = ACLERRNOMEM;
  1154. eid = ACLERR1920;
  1155. nserrGenerate(errp, rv, eid, ACL_Program, 0);
  1156. } else if ( acl_Parse() ) {
  1157. rv = ACLERRPARSE;
  1158. eid = ACLERR1780;
  1159. }
  1160. if ( acl_EndScanner() < 0 ) {
  1161. rv = ACLERROPEN;
  1162. eid = ACLERR1500;
  1163. errmsg = system_errmsg();
  1164. nserrGenerate(errp, rv, eid, ACL_Program, 2, "buffer", errmsg);
  1165. }
  1166. }
  1167. if ( rv || eid ) {
  1168. ACL_ListDestroy(errp, handle);
  1169. handle = NULL;
  1170. }
  1171. crit_exit( acl_parse_crit );
  1172. return(handle);
  1173. }
  1174. /*
  1175. * Delete a named ACL from an ACL list
  1176. *
  1177. * Input:
  1178. * acl_list Target ACL list handle
  1179. * acl_name Name of the target ACL
  1180. * Returns:
  1181. * 0 success
  1182. * < 0 failure
  1183. */
  1184. NSAPI_PUBLIC int
  1185. ACL_ListAclDelete(NSErr_t *errp, ACLListHandle_t *acl_list, char *acl_name, int flags )
  1186. {
  1187. ACLHandle_t *acl = NULL;
  1188. ACLWrapper_t *wrapper;
  1189. ACLWrapper_t *wrapper_prev = NULL;
  1190. Symbol_t *sym;
  1191. if ( acl_list == NULL || acl_name == NULL )
  1192. return(ACLERRUNDEF);
  1193. if ( flags & ACL_CASE_INSENSITIVE ) {
  1194. for ( wrapper = acl_list->acl_list_head; wrapper != NULL;
  1195. wrapper = wrapper->wrap_next ) {
  1196. if ( wrapper->acl->tag &&
  1197. strcasecmp( wrapper->acl->tag, acl_name ) == 0 ) {
  1198. acl = wrapper->acl;
  1199. break;
  1200. }
  1201. wrapper_prev = wrapper;
  1202. }
  1203. } else {
  1204. for ( wrapper = acl_list->acl_list_head; wrapper != NULL;
  1205. wrapper = wrapper->wrap_next ) {
  1206. if ( wrapper->acl->tag &&
  1207. strcmp( wrapper->acl->tag, acl_name ) == 0 ) {
  1208. acl = wrapper->acl;
  1209. break;
  1210. }
  1211. wrapper_prev = wrapper;
  1212. }
  1213. }
  1214. if ( acl ) {
  1215. if ( wrapper_prev ) {
  1216. wrapper_prev->wrap_next = wrapper->wrap_next;
  1217. } else {
  1218. acl_list->acl_list_head = wrapper->wrap_next;
  1219. }
  1220. if ( acl_list->acl_list_tail == wrapper ) {
  1221. acl_list->acl_list_tail = wrapper_prev;
  1222. }
  1223. acl = wrapper->acl;
  1224. acl_list->acl_count--;
  1225. PERM_FREE(wrapper);
  1226. if ( acl_list->acl_sym_table ) {
  1227. if ( symTableFindSym(acl_list->acl_sym_table,
  1228. acl->tag, ACLSYMACL, (void **) &sym) < 0 ) {
  1229. /* not found, this is an error of some sort */
  1230. } else {
  1231. symTableRemoveSym(acl_list->acl_sym_table, sym);
  1232. acl_hash_entry_destroy(sym, 0);
  1233. }
  1234. }
  1235. ACL_AclDestroy(errp, acl);
  1236. return(0);
  1237. }
  1238. return(ACLERRUNDEF);
  1239. }
  1240. /*
  1241. * Destroy a NameList
  1242. *
  1243. * Input:
  1244. * name_list a dynamically allocated array of strings
  1245. * Returns:
  1246. * 0 success
  1247. * < 0 failure
  1248. */
  1249. NSAPI_PUBLIC int
  1250. ACL_NameListDestroy(NSErr_t *errp, char **name_list)
  1251. {
  1252. int list_index;
  1253. if ( name_list == NULL )
  1254. return(ACLERRUNDEF);
  1255. for ( list_index = 0; name_list[list_index]; list_index++ ) {
  1256. PERM_FREE(name_list[list_index]);
  1257. }
  1258. PERM_FREE(name_list);
  1259. return(0);
  1260. }
  1261. /*
  1262. * Gets a name list of consisting of all ACL names for input list.
  1263. *
  1264. * Input:
  1265. * acl_list an ACL List handle
  1266. * name_list pointer to a list of string pointers
  1267. * Returns:
  1268. * 0 success
  1269. * < 0 failure
  1270. */
  1271. NSAPI_PUBLIC int
  1272. ACL_ListGetNameList(NSErr_t *errp, ACLListHandle_t *acl_list, char ***name_list)
  1273. {
  1274. const int block_size = 50;
  1275. ACLWrapper_t *wrapper;
  1276. int list_index;
  1277. int list_size;
  1278. char **tmp_list;
  1279. char **local_list;
  1280. const char *name;
  1281. if ( acl_list == NULL )
  1282. return(ACLERRUNDEF);
  1283. list_size = block_size;
  1284. local_list = (char **) PERM_MALLOC(sizeof(char *) * list_size);
  1285. if ( local_list == NULL )
  1286. return(ACLERRNOMEM);
  1287. list_index = 0;
  1288. local_list[list_index] = NULL;
  1289. for ( wrapper = acl_list->acl_list_head; wrapper != NULL;
  1290. wrapper = wrapper->wrap_next ) {
  1291. if ( wrapper->acl->tag )
  1292. name = wrapper->acl->tag;
  1293. else
  1294. name = "noname";
  1295. if ( list_index + 2 > list_size ) {
  1296. list_size += block_size;
  1297. tmp_list = (char **) PERM_REALLOC(local_list,
  1298. sizeof(char *) * list_size);
  1299. if ( tmp_list == NULL ) {
  1300. ACL_NameListDestroy(errp, local_list);
  1301. return(ACLERRNOMEM);
  1302. }
  1303. local_list = tmp_list;
  1304. }
  1305. local_list[list_index] = PERM_STRDUP(name);
  1306. if ( local_list[list_index] == NULL ) {
  1307. ACL_NameListDestroy(errp, local_list);
  1308. return(ACLERRNOMEM);
  1309. }
  1310. list_index++;
  1311. local_list[list_index] = NULL;
  1312. }
  1313. *name_list = local_list;
  1314. return(0);
  1315. }
  1316. /*
  1317. * Changes method to method plus DBTYPE, and registers
  1318. * databases.
  1319. *
  1320. * Input:
  1321. * errp error stack
  1322. * acl_list Target ACL list handle
  1323. * Returns:
  1324. * 0 success
  1325. * < 0 failure
  1326. */
  1327. NSAPI_PUBLIC int
  1328. ACL_ListPostParseForAuth(NSErr_t *errp, ACLListHandle_t *acl_list )
  1329. {
  1330. ACLHandle_t *acl;
  1331. ACLWrapper_t *wrap;
  1332. ACLExprHandle_t *expr;
  1333. char *method;
  1334. char *database;
  1335. int rv;
  1336. ACLDbType_t *dbtype;
  1337. ACLMethod_t *methodtype;
  1338. if ( acl_list == NULL )
  1339. return(0);
  1340. for ( wrap = acl_list->acl_list_head; wrap; wrap = wrap->wrap_next ) {
  1341. acl = wrap->acl;
  1342. if ( acl == NULL )
  1343. continue;
  1344. for ( expr = acl->expr_list_head; expr; expr = expr->expr_next ) {
  1345. if ( expr->expr_type != ACL_EXPR_TYPE_AUTH ||
  1346. expr->expr_auth == NULL)
  1347. continue;
  1348. rv = PListGetValue(expr->expr_auth, ACL_ATTR_METHOD_INDEX,
  1349. (void **) &method, NULL);
  1350. if ( rv >= 0 ) {
  1351. methodtype = (ACLMethod_t *)PERM_MALLOC(sizeof(ACLMethod_t));
  1352. rv = ACL_MethodFind(errp, method, methodtype);
  1353. if (rv) {
  1354. nserrGenerate(errp, ACLERRUNDEF, ACLERR3800, ACL_Program,
  1355. 3, acl->tag, "method", method);
  1356. PERM_FREE(methodtype);
  1357. return(ACLERRUNDEF);
  1358. }
  1359. rv = PListSetValue(expr->expr_auth, ACL_ATTR_METHOD_INDEX,
  1360. methodtype, NULL);
  1361. if ( rv < 0 ) {
  1362. nserrGenerate(errp, ACLERRNOMEM, ACLERR3810, ACL_Program,
  1363. 0);
  1364. return(ACLERRNOMEM);
  1365. }
  1366. PERM_FREE(method);
  1367. }
  1368. rv = PListGetValue(expr->expr_auth, ACL_ATTR_DATABASE_INDEX,
  1369. (void **) &database, NULL);
  1370. if (rv < 0) continue;
  1371. /* The following function lets user use databases which are
  1372. * not registered by their administrators. This also fixes
  1373. * the backward compatibility.
  1374. */
  1375. dbtype = (ACLDbType_t *)PERM_MALLOC(sizeof(ACLDbType_t));
  1376. rv = ACL_RegisterDbFromACL(errp, (const char *) database,
  1377. dbtype);
  1378. if (rv < 0) {
  1379. nserrGenerate(errp, ACLERRUNDEF, ACLERR3800, ACL_Program,
  1380. 3, acl->tag, "database", database);
  1381. PERM_FREE(dbtype);
  1382. return(ACLERRUNDEF);
  1383. }
  1384. rv = PListInitProp(expr->expr_auth, ACL_ATTR_DBTYPE_INDEX, ACL_ATTR_DBTYPE,
  1385. dbtype, NULL);
  1386. if ( rv < 0 ) {
  1387. nserrGenerate(errp, ACLERRNOMEM, ACLERR3810, ACL_Program,
  1388. 0);
  1389. return(ACLERRNOMEM);
  1390. }
  1391. }
  1392. }
  1393. return(0);
  1394. }
  1395. /*
  1396. * The following routines are used to validate input parameters. They always
  1397. * return 1, or cause an PR_ASSERT failure. The proper way to use them is
  1398. * with an PR_ASSERT in the calling function. E.g.
  1399. * PR_ASSERT(ACL_AssertAcllist(acllist));
  1400. */
  1401. int
  1402. ACL_AssertAcllist(ACLListHandle_t *acllist)
  1403. {
  1404. ACLWrapper_t *wrap;
  1405. if (acllist == ACL_LIST_NO_ACLS) return 1;
  1406. PR_ASSERT(acllist);
  1407. PR_ASSERT(acllist->acl_list_head);
  1408. PR_ASSERT(acllist->acl_list_tail);
  1409. PR_ASSERT(acllist->acl_count);
  1410. PR_ASSERT(acllist->ref_count > 0);
  1411. for (wrap=acllist->acl_list_head; wrap; wrap=wrap->wrap_next) {
  1412. PR_ASSERT(ACL_AssertAcl(wrap->acl));
  1413. }
  1414. /* Artificially limit ACL lists to 10 ACLs for now */
  1415. PR_ASSERT(acllist->acl_count < 10);
  1416. return 1;
  1417. }
  1418. int
  1419. ACL_AssertAcl(ACLHandle_t *acl)
  1420. {
  1421. PR_ASSERT(acl);
  1422. PR_ASSERT(acl->ref_count);
  1423. PR_ASSERT(acl->expr_count);
  1424. PR_ASSERT(acl->expr_list_head);
  1425. PR_ASSERT(acl->expr_list_tail);
  1426. return 1;
  1427. }
  1428. static PList_t ACLAttr2IndexPList = NULL;
  1429. int
  1430. ACL_InitAttr2Index(void)
  1431. {
  1432. intptr_t i;
  1433. if (ACLAttr2IndexPList) return 0;
  1434. ACLAttr2IndexPList = PListNew(NULL);
  1435. for (i = 1; i < ACL_ATTR_INDEX_MAX; i++) {
  1436. PListInitProp(ACLAttr2IndexPList, 0, ACLAttrTable[i], (const void *)i, NULL);
  1437. }
  1438. return 0;
  1439. }
  1440. /*
  1441. * Attempt to locate the index number for one of the known attribute names
  1442. * that are stored in plists. If we can't match it, just return 0.
  1443. */
  1444. int
  1445. ACL_Attr2Index(const char *attrname)
  1446. {
  1447. int index = 0;
  1448. if ( ACLAttr2IndexPList ) {
  1449. PListFindValue(ACLAttr2IndexPList, attrname, (void **)&index, NULL);
  1450. if (index < 0) index = 0;
  1451. }
  1452. return index;
  1453. }
  1454. void
  1455. ACL_Attr2IndexListDestroy(void)
  1456. {
  1457. PListDestroy(ACLAttr2IndexPList);
  1458. if(acl_parse_crit)
  1459. crit_terminate(acl_parse_crit);
  1460. acl_free_buffer();
  1461. }