acct_util.c 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270
  1. /******************************************************************************
  2. Copyright (C) 2009 Hewlett-Packard Development Company, L.P.
  3. This program is free software; you can redistribute it and/or
  4. modify it under the terms of the GNU General Public License
  5. version 2 as published by the Free Software Foundation.
  6. This program is distributed in the hope that it will be useful,
  7. but WITHOUT ANY WARRANTY; without even the implied warranty of
  8. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  9. GNU General Public License for more details.
  10. You should have received a copy of the GNU General Public License
  11. along with this program; if not, write to the Free Software
  12. Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  13. Contributors:
  14. Hewlett-Packard Development Company, L.P.
  15. ******************************************************************************/
  16. #include <stdio.h>
  17. #include <stdlib.h>
  18. #include <string.h>
  19. #include <time.h>
  20. #include <ctype.h>
  21. #include "slapi-plugin.h"
  22. #include "acctpolicy.h"
  23. /* Globals */
  24. static void* plugin_id = NULL;
  25. /*
  26. Checks whether an entry has a particular attribute type, and optionally
  27. returns the value. Only for use with single-valued attributes - it returns
  28. the first value it finds.
  29. */
  30. int
  31. has_attr( Slapi_Entry* target_entry, char* attr_name, char** val ) {
  32. Slapi_ValueSet *values = NULL;
  33. Slapi_Value* sval;
  34. char *actual_type_name = NULL;
  35. int type_name_disposition = 0, attr_free_flags = 0, rc = 0;
  36. /* Use vattr interface to support virtual attributes, e.g.
  37. acctPolicySubentry has a good chance of being supplied by CoS */
  38. if ( slapi_vattr_values_get( target_entry, attr_name, &values, &type_name_disposition, &actual_type_name, 0, &attr_free_flags) == 0) {
  39. if( slapi_valueset_first_value( values, &sval ) == -1 ) {
  40. rc = 0;
  41. } else {
  42. rc = 1;
  43. if( val ) {
  44. /* Caller wants a copy of the found attribute's value */
  45. *val = slapi_ch_strdup( slapi_value_get_string( sval ) );
  46. }
  47. }
  48. } else {
  49. rc = 0;
  50. }
  51. slapi_vattr_values_free(&values, &actual_type_name, attr_free_flags);
  52. return( rc );
  53. }
  54. /*
  55. Lazy wrapper for has_attr()
  56. */
  57. char*
  58. get_attr_string_val( Slapi_Entry* target_entry, char* attr_name ) {
  59. char* ret = NULL;
  60. has_attr( target_entry, attr_name, &ret );
  61. return( ret );
  62. }
  63. /*
  64. Given an entry, provide the account policy in effect for that entry.
  65. Returns non-0 if function fails. If account policy comes back NULL, it's
  66. not an error; the entry is simply not covered by a policy.
  67. */
  68. int
  69. get_acctpolicy( Slapi_PBlock *pb, Slapi_Entry *target_entry, void *plugin_id,
  70. acctPolicy **policy ) {
  71. Slapi_DN *sdn = NULL;
  72. Slapi_Entry *policy_entry = NULL;
  73. Slapi_Attr *attr;
  74. Slapi_Value *sval = NULL;
  75. int ldrc;
  76. char *attr_name;
  77. char *policy_dn = NULL;
  78. acctPluginCfg *cfg;
  79. int rc = 0;
  80. cfg = get_config();
  81. if( policy == NULL ) {
  82. /* Bad parameter */
  83. return( -1 );
  84. }
  85. *policy = NULL;
  86. /* Return success and NULL policy */
  87. policy_dn = get_attr_string_val( target_entry, cfg->spec_attr_name );
  88. if( policy_dn == NULL ) {
  89. slapi_log_error( SLAPI_LOG_PLUGIN, PLUGIN_NAME,
  90. "\"%s\" is not governed by an account inactivity "
  91. "policy subentry\n", slapi_entry_get_ndn( target_entry ) );
  92. if (cfg->inactivitylimit != ULONG_MAX) {
  93. goto dopolicy;
  94. }
  95. slapi_log_error( SLAPI_LOG_PLUGIN, PLUGIN_NAME,
  96. "\"%s\" is not governed by an account inactivity "
  97. "global policy\n", slapi_entry_get_ndn( target_entry ) );
  98. return rc;
  99. }
  100. sdn = slapi_sdn_new_dn_byref( policy_dn );
  101. ldrc = slapi_search_internal_get_entry( sdn, NULL, &policy_entry,
  102. plugin_id );
  103. slapi_sdn_free( &sdn );
  104. /* There should be a policy but it can't be retrieved; fatal error */
  105. if( policy_entry == NULL ) {
  106. if( ldrc != LDAP_NO_SUCH_OBJECT ) {
  107. slapi_log_error( SLAPI_LOG_FATAL, PLUGIN_NAME,
  108. "Error retrieving policy entry \"%s\": %d\n", policy_dn, ldrc );
  109. } else {
  110. slapi_log_error( SLAPI_LOG_PLUGIN, PLUGIN_NAME,
  111. "Policy entry \"%s\" is missing: %d\n", policy_dn, ldrc );
  112. }
  113. rc = -1;
  114. goto done;
  115. }
  116. dopolicy:
  117. *policy = (acctPolicy *)slapi_ch_calloc( 1, sizeof( acctPolicy ) );
  118. if ( !policy_entry ) { /* global policy */
  119. (*policy)->inactivitylimit = cfg->inactivitylimit;
  120. goto done;
  121. }
  122. for( slapi_entry_first_attr( policy_entry, &attr ); attr != NULL;
  123. slapi_entry_next_attr( policy_entry, attr, &attr ) ) {
  124. slapi_attr_get_type(attr, &attr_name);
  125. if( !strcasecmp( attr_name, cfg->limit_attr_name ) ) {
  126. if( slapi_attr_first_value( attr, &sval ) == 0 ) {
  127. (*policy)->inactivitylimit = slapi_value_get_ulong( sval );
  128. }
  129. }
  130. }
  131. done:
  132. slapi_ch_free_string( &policy_dn );
  133. slapi_entry_free( policy_entry );
  134. return( rc );
  135. }
  136. /*
  137. Frees an account policy allocated by get_acctpolicy()
  138. */
  139. void
  140. free_acctpolicy( acctPolicy **policy ) {
  141. slapi_ch_free( (void**)policy );
  142. return;
  143. }
  144. /*
  145. Plugin plumbing
  146. */
  147. void
  148. set_identity(void *identity) {
  149. plugin_id = identity;
  150. }
  151. /*
  152. Plugin plumbing
  153. */
  154. void*
  155. get_identity() {
  156. return( plugin_id );
  157. }
  158. /*
  159. A more flexible atoi(), converts to integer and returns the characters
  160. between (src+offset) and (src+offset+len). No support for negative numbers,
  161. which doesn't affect our time parsing.
  162. */
  163. int
  164. antoi( char *src, int offset, int len ) {
  165. int pow = 1, res = 0;
  166. if( len < 0 ) {
  167. return( -1 );
  168. }
  169. while( --len != -1 ) {
  170. if( !isdigit( src[offset+len] ) ) {
  171. res = -1;
  172. break;
  173. } else {
  174. res += ( src[offset+len] - '0' ) * pow ;
  175. pow *= 10;
  176. }
  177. }
  178. return( res );
  179. }
  180. /*
  181. Converts generalized time to UNIX GMT time. For example:
  182. "20060807211257Z" -> 1154981577
  183. */
  184. time_t
  185. gentimeToEpochtime( char *gentimestr ) {
  186. time_t epochtime, cur_local_epochtime, cur_gm_epochtime, zone_offset;
  187. struct tm t, *cur_gm_time;
  188. /* Find the local offset from GMT */
  189. cur_gm_time = (struct tm*)slapi_ch_calloc( 1, sizeof( struct tm ) );
  190. cur_local_epochtime = time( (time_t)0 );
  191. gmtime_r( &cur_local_epochtime, cur_gm_time );
  192. cur_gm_epochtime = mktime( cur_gm_time );
  193. free( cur_gm_time );
  194. zone_offset = cur_gm_epochtime - cur_local_epochtime;
  195. /* Parse generalizedtime string into a tm struct */
  196. t.tm_year = antoi( gentimestr, 0, 4 ) - 1900;
  197. t.tm_mon = antoi( gentimestr, 4, 2 ) - 1;
  198. t.tm_mday = antoi( gentimestr, 6, 2 );
  199. t.tm_hour = antoi( gentimestr, 8, 2 );
  200. t.tm_min = antoi( gentimestr, 10, 2 );
  201. t.tm_sec = antoi( gentimestr, 12, 2 );
  202. t.tm_isdst = 0; /* DST does not apply to UTC */
  203. /* Turn tm object into local epoch time */
  204. epochtime = mktime( &t );
  205. /* Turn local epoch time into GMT epoch time */
  206. epochtime -= zone_offset;
  207. return( epochtime );
  208. }
  209. /*
  210. Converts UNIX time to generalized time. For example:
  211. 1154981577 -> "20060807211257Z"
  212. */
  213. char*
  214. epochtimeToGentime( time_t epochtime ) {
  215. char *gentimestr;
  216. struct tm t;
  217. gmtime_r( &epochtime, &t );
  218. gentimestr = slapi_ch_malloc( 20 );
  219. /* Format is YYYYmmddHHMMSSZ (15+1 chars) */
  220. strftime( gentimestr, 16, "%Y%m%d%H%M%SZ", &t );
  221. return( gentimestr );
  222. }
  223. int update_is_allowed_attr (const char *attr)
  224. {
  225. int i;
  226. /* check list of attributes that cannot be used for login recording */
  227. for (i = 0; protected_attrs_login_recording[i]; i ++) {
  228. if (strcasecmp (attr, protected_attrs_login_recording[i]) == 0) {
  229. /* this attribute is not allowed */
  230. return 0;
  231. }
  232. }
  233. return 1;
  234. }