plugin_acl.c 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  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. * plugin_acl.c - routines for calling access control plugins
  14. */
  15. #include "slap.h"
  16. static int
  17. acl_default_access ( Slapi_PBlock *pb , Slapi_Entry *e, int access)
  18. {
  19. int isRoot, rootdse, accessCheckDisabled;
  20. int rc;
  21. slapi_pblock_get ( pb, SLAPI_REQUESTOR_ISROOT, &isRoot);
  22. if ( isRoot ) return LDAP_SUCCESS;
  23. rc = slapi_pblock_get ( pb, SLAPI_PLUGIN_DB_NO_ACL, &accessCheckDisabled );
  24. if ( rc != -1 && accessCheckDisabled ) return LDAP_SUCCESS;
  25. rootdse = slapi_is_rootdse ( slapi_entry_get_ndn ( e ) );
  26. if ( rootdse && (access & (SLAPI_ACL_READ | SLAPI_ACL_SEARCH) ) )
  27. return LDAP_SUCCESS;
  28. return LDAP_INSUFFICIENT_ACCESS;
  29. }
  30. int
  31. plugin_call_acl_plugin ( Slapi_PBlock *pb, Slapi_Entry *e, char **attrs,
  32. struct berval *val, int access , int flags, char **errbuf)
  33. {
  34. struct slapdplugin *p;
  35. int rc = LDAP_INSUFFICIENT_ACCESS;
  36. int aclplugin_initialized = 0;
  37. Operation *operation;
  38. slapi_pblock_get (pb, SLAPI_OPERATION, &operation);
  39. /* we don't perform acl check for internal operations and if the plugin has set it not to be checked */
  40. if (operation_is_flag_set(operation, SLAPI_OP_FLAG_NO_ACCESS_CHECK|OP_FLAG_INTERNAL|OP_FLAG_REPLICATED|OP_FLAG_LEGACY_REPLICATION_DN))
  41. return LDAP_SUCCESS;
  42. /* call the global plugins first and then the backend specific */
  43. for ( p = get_plugin_list(PLUGIN_LIST_ACL); p != NULL; p = p->plg_next ) {
  44. if (plugin_invoke_plugin_sdn (p, SLAPI_PLUGIN_ACL_ALLOW_ACCESS, pb,
  45. (Slapi_DN*)slapi_entry_get_sdn_const (e))){
  46. aclplugin_initialized = 1;
  47. rc = (*p->plg_acl_access_allowed)(pb, e, attrs, val, access, flags, errbuf);
  48. if ( rc != LDAP_SUCCESS ) break;
  49. }
  50. }
  51. if (! aclplugin_initialized ) {
  52. rc = acl_default_access ( pb, e, access);
  53. }
  54. return rc;
  55. }
  56. int
  57. plugin_call_acl_mods_access ( Slapi_PBlock *pb, Slapi_Entry *e, LDAPMod **mods, char **errbuf )
  58. {
  59. struct slapdplugin *p;
  60. int aclplugin_initialized = 0;
  61. int rc = LDAP_INSUFFICIENT_ACCESS;
  62. Operation *operation;
  63. slapi_pblock_get (pb, SLAPI_OPERATION, &operation);
  64. /* we don't perform acl check for internal operations and if the plugin has set it not to be checked */
  65. if (operation_is_flag_set(operation, SLAPI_OP_FLAG_NO_ACCESS_CHECK|OP_FLAG_INTERNAL|OP_FLAG_REPLICATED|OP_FLAG_LEGACY_REPLICATION_DN))
  66. return LDAP_SUCCESS;
  67. /* call the global plugins first and then the backend specific */
  68. for ( p = get_plugin_list(PLUGIN_LIST_ACL); p != NULL; p = p->plg_next ) {
  69. if (plugin_invoke_plugin_sdn (p, SLAPI_PLUGIN_ACL_MODS_ALLOWED, pb,
  70. (Slapi_DN*)slapi_entry_get_sdn_const (e))){
  71. aclplugin_initialized = 1;
  72. rc = (*p->plg_acl_mods_allowed)( pb, e, mods, errbuf );
  73. if ( rc != LDAP_SUCCESS ) break;
  74. }
  75. }
  76. if (! aclplugin_initialized ) {
  77. rc = acl_default_access ( pb, e, SLAPI_ACL_WRITE);
  78. }
  79. return rc;
  80. }
  81. /* This plugin should be called immediatly after the changes have been comitted */
  82. /* This function is now fully executed for internal and replicated ops. */
  83. int
  84. plugin_call_acl_mods_update ( Slapi_PBlock *pb, int optype )
  85. {
  86. struct slapdplugin *p;
  87. int rc = 0;
  88. void *change = NULL;
  89. void *mychange[2];
  90. Slapi_Entry *te = NULL;
  91. Slapi_DN *sdn = NULL;
  92. Operation *operation;
  93. slapi_pblock_get (pb, SLAPI_OPERATION, &operation);
  94. (void)slapi_pblock_get( pb, SLAPI_TARGET_SDN, &sdn );
  95. switch ( optype ) {
  96. case SLAPI_OPERATION_MODIFY:
  97. (void)slapi_pblock_get( pb, SLAPI_MODIFY_MODS, &change );
  98. break;
  99. case SLAPI_OPERATION_ADD:
  100. (void)slapi_pblock_get( pb, SLAPI_ADD_ENTRY, &change );
  101. te = (Slapi_Entry *)change;
  102. if(!slapi_sdn_isempty(slapi_entry_get_sdn(te)))
  103. {
  104. sdn = slapi_entry_get_sdn(te);
  105. }
  106. break;
  107. case SLAPI_OPERATION_MODRDN:
  108. {
  109. char *newrdn = NULL;
  110. Slapi_DN *psdn = NULL;
  111. char *pdn = NULL;
  112. /* newrdn: "change" is normalized but not case-ignored */
  113. /* The acl plugin expects normalized newrdn, but no need to be case-
  114. * ignored. */
  115. (void)slapi_pblock_get( pb, SLAPI_MODRDN_NEWRDN, &newrdn );
  116. (void)slapi_pblock_get( pb, SLAPI_MODRDN_NEWSUPERIOR_SDN, &psdn );
  117. if (psdn) {
  118. pdn = (char *)slapi_sdn_get_dn(psdn);
  119. } else {
  120. (void)slapi_pblock_get( pb, SLAPI_MODRDN_NEWSUPERIOR, &pdn );
  121. }
  122. mychange[0] = newrdn;
  123. mychange[1] = pdn;
  124. change = mychange;
  125. break;
  126. }
  127. }
  128. if (NULL == sdn) {
  129. LDAPDebug0Args ( LDAP_DEBUG_ANY,
  130. "plugin_call_acl_mods_update: Null target DN\n" );
  131. return LDAP_INVALID_DN_SYNTAX;
  132. }
  133. /* call the global plugins first and then the backend specific */
  134. for ( p = get_plugin_list(PLUGIN_LIST_ACL); p != NULL; p = p->plg_next ) {
  135. if (plugin_invoke_plugin_sdn(p, SLAPI_PLUGIN_ACL_MODS_UPDATE, pb, sdn)){
  136. rc = (*p->plg_acl_mods_update)(pb, optype, sdn, change );
  137. if ( rc != LDAP_SUCCESS ) break;
  138. }
  139. }
  140. return rc;
  141. }
  142. int
  143. plugin_call_acl_verify_syntax ( Slapi_PBlock *pb, Slapi_Entry *e, char **errbuf )
  144. {
  145. struct slapdplugin *p;
  146. int rc = 0;
  147. int plugin_called = 0;
  148. Operation *operation;
  149. slapi_pblock_get (pb, SLAPI_OPERATION, &operation);
  150. /* we don't perform acl check for internal operations and if the plugin has set it not to be checked */
  151. if (operation_is_flag_set(operation, SLAPI_OP_FLAG_NO_ACCESS_CHECK|OP_FLAG_INTERNAL|OP_FLAG_REPLICATED|OP_FLAG_LEGACY_REPLICATION_DN))
  152. return LDAP_SUCCESS;
  153. /* call the global plugins first and then the backend specific */
  154. for ( p = get_plugin_list(PLUGIN_LIST_ACL); p != NULL; p = p->plg_next ) {
  155. if (plugin_invoke_plugin_sdn (p, SLAPI_PLUGIN_ACL_SYNTAX_CHECK, pb,
  156. (Slapi_DN*)slapi_entry_get_sdn_const (e))){
  157. plugin_called = 1;
  158. rc = (*p->plg_acl_syntax_check)( pb, e, errbuf );
  159. if ( rc != LDAP_SUCCESS ) break;
  160. }
  161. }
  162. if ( !plugin_called ) {
  163. LDAPDebug ( LDAP_DEBUG_ANY, "The ACL plugin is not initialized. The aci syntax cannot be verified\n",0,0,0);
  164. }
  165. return rc;
  166. }
  167. int slapi_access_allowed( Slapi_PBlock *pb, Slapi_Entry *e, char *attr,
  168. struct berval *val, int access )
  169. {
  170. char *attrs[2] = { NULL, NULL };
  171. attrs[0] = attr;
  172. return ( plugin_call_acl_plugin ( pb, e, attrs, val, access, ACLPLUGIN_ACCESS_DEFAULT, NULL ) );
  173. }
  174. int slapi_acl_check_mods( Slapi_PBlock *pb, Slapi_Entry *e, LDAPMod **mods, char **errbuf )
  175. {
  176. return ( plugin_call_acl_mods_access ( pb, e, mods, errbuf ) );
  177. }
  178. int slapi_acl_verify_aci_syntax (Slapi_PBlock *pb, Slapi_Entry *e, char **errbuf)
  179. {
  180. return ( plugin_call_acl_verify_syntax ( pb, e, errbuf ) );
  181. }