7bit.c 19 KB

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