7bit.c 22 KB

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