7bit.c 20 KB

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