7bit.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790
  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. * 7bit.c
  14. *
  15. * Implements a directory server pre-operation plugin to test
  16. * attributes for 7 bit clean within a defined subtree in the
  17. * directory.
  18. *
  19. */
  20. #include <stdio.h>
  21. #include <slapi-plugin.h>
  22. #include <slapi-private.h>
  23. #include <string.h>
  24. /* DBDB this should be pulled from a common header file */
  25. #if defined( LDAP_ERROR_LOGGING ) && !defined( DEBUG )
  26. #define DEBUG
  27. #endif
  28. /*
  29. * ISSUES:
  30. * How should this plugin handle ACL issues? It seems wrong to reject
  31. * adds and modifies because there is already a conflicting UID, when
  32. * the request would have failed because of an ACL check anyway.
  33. *
  34. * This code currently defines a maximum filter string size of 512. Is
  35. * this large enough?
  36. *
  37. * This code currently does not quote the value portion of the filter as
  38. * it is created. This is a bug.
  39. */
  40. /* */
  41. #define BEGIN do {
  42. #define END } while(0);
  43. /*
  44. * Slapi plugin descriptor
  45. */
  46. static char *plugin_name = "NS7bitAttr";
  47. static Slapi_PluginDesc
  48. pluginDesc = { "NS7bitAttr", VENDOR, DS_PACKAGE_VERSION,
  49. "Enforce 7-bit clean attribute values" };
  50. /*
  51. * More information about constraint failure
  52. */
  53. static char *moreInfo =
  54. "The value is not 7-bit clean: ";
  55. /* ------------------------------------------------------------ */
  56. /*
  57. * op_error - Record (and report) an operational error.
  58. */
  59. static int
  60. op_error(int internal_error)
  61. {
  62. slapi_log_err(SLAPI_LOG_PLUGIN, plugin_name,
  63. "op_error - %d\n", internal_error);
  64. return LDAP_OPERATIONS_ERROR;
  65. }
  66. static void
  67. issue_error(Slapi_PBlock *pb, int result, char *type, char *value)
  68. {
  69. char *moreinfop;
  70. slapi_log_err(SLAPI_LOG_PLUGIN, plugin_name,
  71. "issue_error - %s result %d\n", type, result);
  72. if (value == NULL) {
  73. value = "unknown";
  74. }
  75. moreinfop = slapi_ch_smprintf("%s%s", moreInfo, value);
  76. /* Send failure to the client */
  77. slapi_send_ldap_result(pb, result, 0, moreinfop, 0, 0);
  78. slapi_ch_free((void **)&moreinfop);
  79. return;
  80. }
  81. /*
  82. * Check 'value' for 7-bit cleanliness.
  83. */
  84. static int
  85. bit_check_one_berval(const struct berval *value, char **violated)
  86. {
  87. int result;
  88. char *ch;
  89. int i;
  90. #ifdef DEBUG
  91. slapi_log_err(SLAPI_LOG_PLUGIN, plugin_name, "bit_check_one_berval - 7-bit checking begin\n");
  92. #endif
  93. result = LDAP_SUCCESS;
  94. /* If no value, can't possibly be a conflict */
  95. if ( (struct berval *)NULL == value )
  96. return result;
  97. for(i=0, ch=value->bv_val; ch && i < (int)(value->bv_len) ;
  98. ch++, i++)
  99. {
  100. if (( 0x80 & *ch ) != 0 )
  101. {
  102. result = LDAP_CONSTRAINT_VIOLATION;
  103. *violated = value->bv_val;
  104. break;
  105. }
  106. }
  107. return result;
  108. }
  109. /*
  110. * Check a set of values for 7-bit cleanliness.
  111. *
  112. * If 'attr' is NULL, the values are taken from 'values'.
  113. * If 'attr' is non-NULL, the values are taken from 'attr'.
  114. */
  115. static int
  116. bit_check(Slapi_Attr *attr, struct berval **values, char **violated)
  117. {
  118. int result = LDAP_SUCCESS;
  119. *violated = NULL;
  120. /* If no values, can't possibly be a conflict */
  121. if ( (Slapi_Attr *)NULL == attr && (struct berval **)NULL == values )
  122. return result;
  123. if ( (Slapi_Attr *)NULL != attr )
  124. {
  125. Slapi_Value *v = NULL;
  126. int vhint = -1;
  127. for ( vhint = slapi_attr_first_value( attr, &v );
  128. vhint != -1 && LDAP_SUCCESS == result;
  129. vhint = slapi_attr_next_value( attr, vhint, &v ))
  130. {
  131. result = bit_check_one_berval(slapi_value_get_berval(v), violated);
  132. }
  133. }
  134. else
  135. {
  136. for (;*values != NULL && LDAP_SUCCESS == result; values++)
  137. {
  138. result = bit_check_one_berval(*values, violated);
  139. }
  140. }
  141. #ifdef DEBUG
  142. slapi_log_err(SLAPI_LOG_PLUGIN, plugin_name,
  143. "bit_check - 7 bit check result = %d\n", result);
  144. #endif
  145. return result;
  146. }
  147. /* ------------------------------------------------------------ */
  148. /*
  149. * preop_add - pre-operation plug-in for add
  150. */
  151. static int
  152. preop_add(Slapi_PBlock *pb)
  153. {
  154. int result;
  155. char *violated = NULL;
  156. char *pwd = NULL;
  157. char *origpwd = NULL;
  158. #ifdef DEBUG
  159. slapi_log_err(SLAPI_LOG_PLUGIN, plugin_name, "preop_add - ADD begin\n");
  160. #endif
  161. result = LDAP_SUCCESS;
  162. /*
  163. * Do constraint check on the added entry. Set result.
  164. */
  165. BEGIN
  166. int err;
  167. int argc;
  168. char **argv;
  169. char **attrName;
  170. const char *dn;
  171. Slapi_DN *sdn = NULL;
  172. Slapi_Entry *e;
  173. char **firstSubtree;
  174. char **subtreeDN;
  175. int subtreeCnt;
  176. int is_replicated_operation;
  177. struct berval *vals[2];
  178. struct berval val;
  179. vals[0] = &val;
  180. vals[1] = NULL;
  181. /*
  182. * Get the arguments
  183. */
  184. err = slapi_pblock_get(pb, SLAPI_PLUGIN_ARGC, &argc);
  185. if (err) { result = op_error(53); break; }
  186. err = slapi_pblock_get(pb, SLAPI_PLUGIN_ARGV, &argv);
  187. if (err) { result = op_error(54); break; }
  188. /*
  189. * If this is a replication update, just be a noop.
  190. */
  191. err = slapi_pblock_get(pb, SLAPI_IS_REPLICATED_OPERATION, &is_replicated_operation);
  192. if (err) { result = op_error(56); break; }
  193. if (is_replicated_operation)
  194. {
  195. break;
  196. }
  197. /*
  198. * Get the target DN for this add operation
  199. */
  200. err = slapi_pblock_get(pb, SLAPI_ADD_TARGET_SDN, &sdn);
  201. if (err) { result = op_error(50); break; }
  202. dn = slapi_sdn_get_dn(sdn);
  203. #ifdef DEBUG
  204. slapi_log_err(SLAPI_LOG_PLUGIN, plugin_name, "preop_add - ADD target=%s\n", dn);
  205. #endif
  206. /*
  207. * Get the entry data for this add. Check whether it
  208. * contains a value for the unique attribute
  209. */
  210. err = slapi_pblock_get(pb, SLAPI_ADD_ENTRY, &e);
  211. if (err) { result = op_error(51); break; }
  212. for ( firstSubtree = argv; strcmp(*firstSubtree, ",") != 0;
  213. firstSubtree++, argc--) {}
  214. firstSubtree++;
  215. argc--;
  216. for (attrName = argv; attrName && *attrName && strcmp(*attrName, ","); attrName++)
  217. {
  218. /*
  219. * if the attribute is userpassword, check unhashed user password
  220. * instead. "userpassword" is encoded; it will always pass the 7bit
  221. * check.
  222. */
  223. char *attr_name = NULL;
  224. Slapi_Attr *attr = NULL;
  225. if ( strcasecmp(*attrName, "userpassword") == 0 )
  226. {
  227. origpwd = pwd = slapi_get_first_clear_text_pw(e);
  228. if (pwd == NULL) {
  229. continue;
  230. }
  231. val.bv_val = pwd;
  232. val.bv_len = strlen(val.bv_val);
  233. } else {
  234. attr_name = *attrName;
  235. err = slapi_entry_attr_find(e, attr_name, &attr);
  236. if (err) continue; /* break;*/ /* no 7-bit attribute */
  237. }
  238. /*
  239. * For each DN in the managed list, do 7-bit checking if
  240. * the target DN is a subnode in the tree.
  241. */
  242. for( subtreeDN=firstSubtree, subtreeCnt=argc ;subtreeCnt > 0;
  243. subtreeCnt--,subtreeDN++)
  244. {
  245. /*
  246. * issuffix determines whether the target is under the
  247. * subtree *subtreeDN
  248. */
  249. if (slapi_dn_issuffix(dn, *subtreeDN))
  250. {
  251. #ifdef DEBUG
  252. slapi_log_err(SLAPI_LOG_PLUGIN, plugin_name,
  253. "preop_add - ADD subtree=%s\n", *subtreeDN);
  254. #endif
  255. /*
  256. * Check if the value is 7-bit clean
  257. */
  258. if(pwd)
  259. {
  260. result = bit_check(attr, vals, &violated);
  261. if(!result)
  262. pwd = NULL;
  263. }
  264. else
  265. result = bit_check(attr, NULL, &violated);
  266. if (result) break;
  267. }
  268. }
  269. /* don't have to go on if there is a value not 7-bit clean */
  270. if (result) break;
  271. }
  272. END
  273. if (result) {
  274. issue_error(pb, result, "ADD", violated);
  275. }
  276. slapi_ch_free_string(&origpwd);
  277. return (result==LDAP_SUCCESS)?0:-1;
  278. }
  279. static void
  280. addMod(LDAPMod ***modary, int *capacity, int *nmods, LDAPMod *toadd)
  281. {
  282. if (*nmods == *capacity) {
  283. *capacity += 4;
  284. if (*modary) {
  285. *modary = (LDAPMod **)slapi_ch_realloc((char *)*modary, *capacity * sizeof(LDAPMod *));
  286. } else {
  287. *modary = (LDAPMod **)slapi_ch_malloc(*capacity * sizeof(LDAPMod *));
  288. }
  289. }
  290. (*modary)[*nmods] = toadd;
  291. (*nmods)++;
  292. }
  293. /* ------------------------------------------------------------ */
  294. /*
  295. * preop_modify - pre-operation plug-in for modify
  296. */
  297. static int
  298. preop_modify(Slapi_PBlock *pb)
  299. {
  300. int result;
  301. char *violated = NULL;
  302. LDAPMod **checkmods = NULL; /* holds mods to check */
  303. int checkmodsCapacity = 0; /* max capacity of checkmods */
  304. #ifdef DEBUG
  305. slapi_log_err(SLAPI_LOG_PLUGIN, plugin_name,
  306. "preop_modify - MODIFY begin\n");
  307. #endif
  308. result = LDAP_SUCCESS;
  309. BEGIN
  310. int err;
  311. int argc;
  312. char **argv;
  313. char **attrName;
  314. LDAPMod **mods;
  315. LDAPMod **firstMods;
  316. LDAPMod *mod;
  317. const char *target;
  318. Slapi_DN *target_sdn = NULL;
  319. char **firstSubtree;
  320. char **subtreeDN;
  321. int subtreeCnt;
  322. int is_replicated_operation;
  323. /*
  324. * Get the arguments
  325. */
  326. err = slapi_pblock_get(pb, SLAPI_PLUGIN_ARGC, &argc);
  327. if (err) { result = op_error(13); break; }
  328. err = slapi_pblock_get(pb, SLAPI_PLUGIN_ARGV, &argv);
  329. if (err) { result = op_error(14); break; }
  330. /*
  331. * If this is a replication update, just be a noop.
  332. */
  333. err = slapi_pblock_get(pb, SLAPI_IS_REPLICATED_OPERATION, &is_replicated_operation);
  334. if (err) { result = op_error(16); break; }
  335. if (is_replicated_operation)
  336. {
  337. break;
  338. }
  339. err = slapi_pblock_get(pb, SLAPI_MODIFY_MODS, &firstMods);
  340. if (err) { result = op_error(10); break; }
  341. /* Get the target DN */
  342. err = slapi_pblock_get(pb, SLAPI_MODIFY_TARGET_SDN, &target_sdn);
  343. if (err) { result = op_error(11); break; }
  344. target = slapi_sdn_get_dn(target_sdn);
  345. /*
  346. * Look for managed trees that include the target
  347. * Arguments before "," are the 7-bit clean attribute names. Arguemnts
  348. * after "," are subtreeDN's.
  349. */
  350. for ( firstSubtree = argv; strcmp(*firstSubtree, ",") != 0;
  351. firstSubtree++, argc--) {}
  352. firstSubtree++;
  353. argc--;
  354. for (attrName = argv; strcmp(*attrName, ",") != 0; attrName++ )
  355. {
  356. int modcount = 0;
  357. int ii = 0;
  358. /*
  359. * if the attribute is userpassword, check unhashed#user#password
  360. * instead. "userpassword" is encoded; it will always pass the 7bit
  361. * check.
  362. */
  363. char *attr_name;
  364. if ( strcasecmp(*attrName, "userpassword") == 0 )
  365. {
  366. attr_name = "unhashed#user#password";
  367. } else {
  368. attr_name = *attrName;
  369. }
  370. /* There may be more than one mod that matches e.g.
  371. changetype: modify
  372. delete: uid
  373. uid: balster1950
  374. -
  375. add: uid
  376. uid: scottg
  377. So, we need to first find all mods that contain the attribute
  378. which are add or replace ops and are bvalue encoded
  379. */
  380. /* find out how many mods meet this criteria */
  381. for(mods=firstMods;mods && *mods;mods++)
  382. {
  383. mod = *mods;
  384. if ((slapi_attr_type_cmp(mod->mod_type, attr_name, 1) == 0) && /* mod contains target attr */
  385. (mod->mod_op & LDAP_MOD_BVALUES) && /* mod is bval encoded (not string val) */
  386. (mod->mod_bvalues && mod->mod_bvalues[0]) && /* mod actually contains some values */
  387. (SLAPI_IS_MOD_ADD(mod->mod_op) || /* mod is add */
  388. SLAPI_IS_MOD_REPLACE(mod->mod_op))) /* mod is replace */
  389. {
  390. addMod(&checkmods, &checkmodsCapacity, &modcount, mod);
  391. }
  392. }
  393. if (modcount == 0) {
  394. continue; /* no mods to check, go to next attr */
  395. }
  396. /*
  397. * stop checking at first mod that fails the check
  398. */
  399. for (ii = 0; (result == 0) && (ii < modcount); ++ii)
  400. {
  401. mod = checkmods[ii];
  402. /*
  403. * For each DN in the managed list, do 7-bit checking if
  404. * the target DN is a subnode in the tree.
  405. */
  406. for( subtreeDN=firstSubtree, subtreeCnt=argc ;subtreeCnt > 0;
  407. subtreeCnt--,subtreeDN++)
  408. {
  409. /*
  410. * issuffix determines whether the target is under the
  411. * subtree *subtreeDN
  412. */
  413. if (slapi_dn_issuffix(target, *subtreeDN))
  414. {
  415. #ifdef DEBUG
  416. slapi_log_err(SLAPI_LOG_PLUGIN, plugin_name,
  417. "preop_modify - MODIFY subtree=%s\n", *subtreeDN);
  418. #endif
  419. /*
  420. * Check if the value is 7-bit clean
  421. */
  422. result = bit_check(NULL, mod->mod_bvalues, &violated);
  423. if (result) break;
  424. }
  425. }
  426. }
  427. /* don't have to go on if there is a value not 7-bit clean */
  428. if (result) break;
  429. }
  430. END
  431. slapi_ch_free((void **)&checkmods);
  432. if (result) {
  433. issue_error(pb, result, "MODIFY", violated);
  434. }
  435. return (result==LDAP_SUCCESS)?0:-1;
  436. }
  437. /* ------------------------------------------------------------ */
  438. /*
  439. * preop_modrdn - Pre-operation call for modify RDN
  440. *
  441. * Check that the new RDN does not include attributes that
  442. * cause a constraint violation
  443. */
  444. static int
  445. preop_modrdn(Slapi_PBlock *pb)
  446. {
  447. int result;
  448. Slapi_Entry *e;
  449. char *violated = NULL;
  450. #ifdef DEBUG
  451. slapi_log_err(SLAPI_LOG_PLUGIN, plugin_name,
  452. "preop_modrdn - MODRDN begin\n");
  453. #endif
  454. /* Init */
  455. result = LDAP_SUCCESS;
  456. e = 0;
  457. BEGIN
  458. int err;
  459. int argc;
  460. char **argv;
  461. char **attrName;
  462. Slapi_DN *target_sdn = NULL;
  463. Slapi_DN *superior = NULL;
  464. char *rdn;
  465. Slapi_Attr *attr;
  466. char **firstSubtree;
  467. char **subtreeDN;
  468. int subtreeCnt;
  469. int is_replicated_operation;
  470. /*
  471. * Get the arguments
  472. */
  473. err = slapi_pblock_get(pb, SLAPI_PLUGIN_ARGC, &argc);
  474. if (err) { result = op_error(30); break; }
  475. err = slapi_pblock_get(pb, SLAPI_PLUGIN_ARGV, &argv);
  476. if (err) { result = op_error(31); break; }
  477. /*
  478. * If this is a replication update, just be a noop.
  479. */
  480. err = slapi_pblock_get(pb, SLAPI_IS_REPLICATED_OPERATION, &is_replicated_operation);
  481. if (err) { result = op_error(16); break; }
  482. if (is_replicated_operation)
  483. {
  484. break;
  485. }
  486. /* Get the DN of the entry being renamed */
  487. err = slapi_pblock_get(pb, SLAPI_MODRDN_TARGET_SDN, &target_sdn);
  488. if (err) { result = op_error(22); break; }
  489. /* Get superior value - unimplemented in 3.0 DS */
  490. err = slapi_pblock_get(pb, SLAPI_MODRDN_NEWSUPERIOR_SDN, &superior);
  491. if (err) { result = op_error(20); break; }
  492. /*
  493. * No superior means the entry is just renamed at
  494. * its current level in the tree. Use the target DN for
  495. * determining which managed tree this belongs to
  496. */
  497. if (!slapi_sdn_get_dn(superior)) superior = target_sdn;
  498. /* Get the new RDN - this has the attribute values */
  499. err = slapi_pblock_get(pb, SLAPI_MODRDN_NEWRDN, &rdn);
  500. if (err) { result = op_error(33); break; }
  501. #ifdef DEBUG
  502. slapi_log_err(SLAPI_LOG_PLUGIN, plugin_name,
  503. "preop_modrdn - MODRDN newrdn=%s\n", rdn);
  504. #endif
  505. /*
  506. * Parse the RDN into attributes by creating a "dummy" entry
  507. * and setting the attributes from the RDN.
  508. *
  509. * The new entry must be freed.
  510. */
  511. e = slapi_entry_alloc();
  512. if (!e) { result = op_error(32); break; }
  513. /* NOTE: strdup on the rdn, since it will be freed when
  514. * the entry is freed */
  515. /* slapi_entry_set_normdn expects rdn normalized, but not decapitalized */
  516. slapi_entry_set_normdn(e, slapi_ch_strdup(rdn));
  517. err = slapi_entry_add_rdn_values(e);
  518. if (err)
  519. {
  520. slapi_log_err(SLAPI_LOG_PLUGIN, plugin_name,
  521. "preop_modrdn - MODRDN bad rdn value=%s\n", rdn);
  522. break; /* Bad DN */
  523. }
  524. /*
  525. * arguments before "," are the 7-bit clean attribute names. Arguments
  526. * after "," are subtreeDN's.
  527. */
  528. for ( firstSubtree = argv; strcmp(*firstSubtree, ",") != 0;
  529. firstSubtree++, argc--) {}
  530. firstSubtree++;
  531. argc--;
  532. /*
  533. * Find out if the node is being moved into one of
  534. * the managed subtrees
  535. */
  536. for (attrName = argv; strcmp(*attrName, ",") != 0; attrName++ )
  537. {
  538. /*
  539. * If the attribute type is userpassword, do not replace it by
  540. * unhashed#user#password because unhashed#user#password does not exist
  541. * in this case.
  542. */
  543. /*
  544. * Find any 7-bit attribute data in the new RDN
  545. */
  546. err = slapi_entry_attr_find(e, *attrName, &attr);
  547. if (err) continue; /* break;*/ /* no 7-bit attribute */
  548. /*
  549. * For each DN in the managed list, do 7-bit checking if
  550. * the target DN is a subnode in the tree.
  551. */
  552. for( subtreeDN=firstSubtree, subtreeCnt=argc ;subtreeCnt > 0;
  553. subtreeCnt--,subtreeDN++)
  554. {
  555. /*
  556. * issuffix determines whether the target is under the
  557. * subtree *subtreeDN
  558. */
  559. if (slapi_dn_issuffix(slapi_sdn_get_dn(superior), *subtreeDN))
  560. {
  561. #ifdef DEBUG
  562. slapi_log_err(SLAPI_LOG_PLUGIN, plugin_name,
  563. "preop_modrdn - MODRDN subtree=%s\n", *subtreeDN);
  564. #endif
  565. /*
  566. * Check if the value is 7-bit clean
  567. */
  568. result = bit_check(attr, NULL, &violated);
  569. if (result) break;
  570. }
  571. }
  572. /* don't have to go on if there is a value not 7-bit clean */
  573. if (result) {
  574. /* WB we need to issue the error before we free slapi_entry, else we
  575. * are triggering a use after free because we free violated.
  576. */
  577. issue_error(pb, result, "MODRDN", violated);
  578. break;
  579. }
  580. }
  581. END
  582. /* Clean-up */
  583. if (e) slapi_entry_free(e);
  584. return (result==LDAP_SUCCESS)?0:-1;
  585. }
  586. /* ------------------------------------------------------------ */
  587. /*
  588. * Initialize the plugin
  589. *
  590. */
  591. int
  592. NS7bitAttr_Init(Slapi_PBlock *pb)
  593. {
  594. int err = 0;
  595. Slapi_Entry *plugin_entry = NULL;
  596. char *plugin_type = NULL;
  597. int preadd = SLAPI_PLUGIN_PRE_ADD_FN;
  598. int premod = SLAPI_PLUGIN_PRE_MODIFY_FN;
  599. int premdn = SLAPI_PLUGIN_PRE_MODRDN_FN;
  600. BEGIN
  601. int attr_count = 0;
  602. int argc;
  603. char **argv;
  604. int valid_suffix = 0;
  605. /* Declare plugin version */
  606. err = slapi_pblock_set(pb, SLAPI_PLUGIN_VERSION,
  607. SLAPI_PLUGIN_VERSION_01);
  608. if (err) break;
  609. if ((slapi_pblock_get(pb, SLAPI_PLUGIN_CONFIG_ENTRY, &plugin_entry) == 0) &&
  610. plugin_entry &&
  611. (plugin_type = slapi_entry_attr_get_charptr(plugin_entry, "nsslapd-plugintype")) &&
  612. plugin_type && strstr(plugin_type, "betxn")) {
  613. preadd = SLAPI_PLUGIN_BE_TXN_PRE_ADD_FN;
  614. premod = SLAPI_PLUGIN_BE_TXN_PRE_MODIFY_FN;
  615. premdn = SLAPI_PLUGIN_BE_TXN_PRE_MODRDN_FN;
  616. }
  617. slapi_ch_free_string(&plugin_type);
  618. /*
  619. * Get and normalize arguments
  620. */
  621. err = slapi_pblock_get(pb, SLAPI_PLUGIN_ARGC, &argc);
  622. if (err) break;
  623. err = slapi_pblock_get(pb, SLAPI_PLUGIN_ARGV, &argv);
  624. if (err) break;
  625. for (attr_count = 0; argv && argv[attr_count]; attr_count++) {
  626. slapi_log_err(SLAPI_LOG_PLUGIN, plugin_name, "NS7bitAttr_Init - %d: %s\n",
  627. attr_count, argv[attr_count]);
  628. }
  629. /*
  630. * Arguments before "," are the 7-bit attribute names. Arguments after
  631. * "," are the subtree DN's.
  632. */
  633. if (argc < 1) { err = -2; break; } /* missing arguments */
  634. attr_count = 0;
  635. for(;*argv && strcmp(*argv, ",") != 0 && argc > 0; attr_count++, argc--, argv++);
  636. if (argc == 0) { err = -3; break; } /* no comma separator */
  637. if(attr_count == 0){ err = -4; break; } /* no attributes */
  638. argv++; argc--;
  639. if(argc == 0){ err = -5; break; } /* no suffix */
  640. for(;argc > 0;argc--, argv++) {
  641. err = slapi_dn_syntax_check(pb, *argv, 1);
  642. if (err) {
  643. slapi_log_err(SLAPI_LOG_ERR, plugin_name, "NS7bitAttr_Init - "
  644. "Invalid suffix: %s\n", *argv);
  645. continue;
  646. }
  647. if (!valid_suffix)
  648. valid_suffix = 1;
  649. char *normdn = slapi_create_dn_string_case("%s", *argv);
  650. slapi_ch_free_string(argv);
  651. *argv = normdn;
  652. }
  653. if (!valid_suffix) { err = -6; break; } /* Invalid suffix list */
  654. /* Provide descriptive information */
  655. err = slapi_pblock_set(pb, SLAPI_PLUGIN_DESCRIPTION,
  656. (void*)&pluginDesc);
  657. if (err) break;
  658. /* Register functions */
  659. err = slapi_pblock_set(pb, preadd, (void*)preop_add);
  660. if (err) break;
  661. err = slapi_pblock_set(pb, premod, (void*)preop_modify);
  662. if (err) break;
  663. err = slapi_pblock_set(pb, premdn, (void*)preop_modrdn);
  664. if (err) break;
  665. END
  666. if (err) {
  667. if(err == -1){
  668. slapi_log_err(SLAPI_LOG_PLUGIN, plugin_name, "NS7bitAttr_Init - Error: %d\n", err);
  669. } else if(err == -2){
  670. slapi_log_err(SLAPI_LOG_ERR, plugin_name, "NS7bitAttr_Init - "
  671. "Invalid plugin arguments - missing arguments\n");
  672. } else if(err == -3){
  673. slapi_log_err(SLAPI_LOG_ERR, plugin_name, "NS7bitAttr_Init - "
  674. "Invalid plugin arguments - missing \",\" separator argument\n");
  675. } else if(err == -4){
  676. slapi_log_err(SLAPI_LOG_ERR, plugin_name, "NS7bitAttr_Init - "
  677. "Invalid plugin arguments - missing attributes\n");
  678. } else if(err == -5){
  679. slapi_log_err(SLAPI_LOG_ERR, plugin_name, "NS7bitAttr_Init - "
  680. "Invalid plugin arguments - missing suffix\n");
  681. } else if(err == -6){
  682. slapi_log_err(SLAPI_LOG_ERR, plugin_name, "NS7bitAttr_Init - "
  683. "Invalid plugin arguments - Invalid suffix list\n");
  684. }
  685. err = -1;
  686. }
  687. else
  688. slapi_log_err(SLAPI_LOG_PLUGIN, plugin_name, "NS7bitAttr_Init - plugin loaded\n");
  689. return err;
  690. }