1 /* $NetBSD: time.c,v 1.3 2021/08/14 16:15:00 christos Exp $ */
2
3 /* time.c - deal with time subsystem */
4 /* $OpenLDAP$ */
5 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
6 *
7 * Copyright 2001-2021 The OpenLDAP Foundation.
8 * Portions Copyright 2001-2003 Pierangelo Masarati.
9 * All rights reserved.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted only as authorized by the OpenLDAP
13 * Public License.
14 *
15 * A copy of this license is available in file LICENSE in the
16 * top-level directory of the distribution or, alternatively, at
17 * <http://www.OpenLDAP.org/license.html>.
18 */
19 /* ACKNOWLEDGEMENTS:
20 * This work was initially developed by Pierangelo Masarati for inclusion
21 * in OpenLDAP Software.
22 */
23
24 #include <sys/cdefs.h>
25 __RCSID("$NetBSD: time.c,v 1.3 2021/08/14 16:15:00 christos Exp $");
26
27 #include "portable.h"
28
29 #include <stdio.h>
30 #include <ac/string.h>
31 #include <ac/time.h>
32
33
34 #include "slap.h"
35 #include <lutil.h>
36 #include "proto-slap.h"
37 #include "back-monitor.h"
38
39 static int
40 monitor_subsys_time_update(
41 Operation *op,
42 SlapReply *rs,
43 Entry *e );
44
45 int
monitor_subsys_time_init(BackendDB * be,monitor_subsys_t * ms)46 monitor_subsys_time_init(
47 BackendDB *be,
48 monitor_subsys_t *ms )
49 {
50 monitor_info_t *mi;
51
52 Entry *e, **ep, *e_time;
53 monitor_entry_t *mp;
54 struct berval bv, value;
55
56 assert( be != NULL );
57
58 ms->mss_update = monitor_subsys_time_update;
59
60 mi = ( monitor_info_t * )be->be_private;
61
62 if ( monitor_cache_get( mi,
63 &ms->mss_ndn, &e_time ) ) {
64 Debug( LDAP_DEBUG_ANY,
65 "monitor_subsys_time_init: "
66 "unable to get entry \"%s\"\n",
67 ms->mss_ndn.bv_val );
68 return( -1 );
69 }
70
71 mp = ( monitor_entry_t * )e_time->e_private;
72 mp->mp_children = NULL;
73 ep = &mp->mp_children;
74
75 BER_BVSTR( &bv, "cn=Start" );
76 e = monitor_entry_stub( &ms->mss_dn, &ms->mss_ndn, &bv,
77 mi->mi_oc_monitoredObject, NULL, NULL );
78 if ( e == NULL ) {
79 Debug( LDAP_DEBUG_ANY,
80 "monitor_subsys_time_init: "
81 "unable to create entry \"%s,%s\"\n",
82 bv.bv_val, ms->mss_ndn.bv_val );
83 return( -1 );
84 }
85 attr_merge_normalize_one( e, mi->mi_ad_monitorTimestamp,
86 &mi->mi_startTime, NULL );
87
88 mp = monitor_entrypriv_create();
89 if ( mp == NULL ) {
90 return -1;
91 }
92 e->e_private = ( void * )mp;
93 mp->mp_info = ms;
94 mp->mp_flags = ms->mss_flags \
95 | MONITOR_F_SUB | MONITOR_F_PERSISTENT;
96
97 if ( monitor_cache_add( mi, e ) ) {
98 Debug( LDAP_DEBUG_ANY,
99 "monitor_subsys_time_init: "
100 "unable to add entry \"%s,%s\"\n",
101 bv.bv_val, ms->mss_ndn.bv_val );
102 return( -1 );
103 }
104
105 *ep = e;
106 ep = &mp->mp_next;
107
108 /*
109 * Current
110 */
111 BER_BVSTR( &bv, "cn=Current" );
112 e = monitor_entry_stub( &ms->mss_dn, &ms->mss_ndn, &bv,
113 mi->mi_oc_monitoredObject, NULL, NULL );
114 if ( e == NULL ) {
115 Debug( LDAP_DEBUG_ANY,
116 "monitor_subsys_time_init: "
117 "unable to create entry \"%s,%s\"\n",
118 bv.bv_val, ms->mss_ndn.bv_val );
119 return( -1 );
120 }
121 attr_merge_normalize_one( e, mi->mi_ad_monitorTimestamp,
122 &mi->mi_startTime, NULL );
123
124 mp = monitor_entrypriv_create();
125 if ( mp == NULL ) {
126 return -1;
127 }
128 e->e_private = ( void * )mp;
129 mp->mp_info = ms;
130 mp->mp_flags = ms->mss_flags \
131 | MONITOR_F_SUB | MONITOR_F_PERSISTENT;
132
133 if ( monitor_cache_add( mi, e ) ) {
134 Debug( LDAP_DEBUG_ANY,
135 "monitor_subsys_time_init: "
136 "unable to add entry \"%s,%s\"\n",
137 bv.bv_val, ms->mss_ndn.bv_val );
138 return( -1 );
139 }
140
141 *ep = e;
142 ep = &mp->mp_next;
143
144 /*
145 * Uptime
146 */
147 BER_BVSTR( &bv, "cn=Uptime" );
148 e = monitor_entry_stub( &ms->mss_dn, &ms->mss_ndn, &bv,
149 mi->mi_oc_monitoredObject, NULL, NULL );
150 if ( e == NULL ) {
151 Debug( LDAP_DEBUG_ANY,
152 "monitor_subsys_time_init: "
153 "unable to create entry \"%s,%s\"\n",
154 bv.bv_val, ms->mss_ndn.bv_val );
155 return( -1 );
156 }
157 BER_BVSTR( &value, "0" );
158 attr_merge_normalize_one( e, mi->mi_ad_monitoredInfo,
159 &value, NULL );
160
161 mp = monitor_entrypriv_create();
162 if ( mp == NULL ) {
163 return -1;
164 }
165 e->e_private = ( void * )mp;
166 mp->mp_info = ms;
167 mp->mp_flags = ms->mss_flags \
168 | MONITOR_F_SUB | MONITOR_F_PERSISTENT;
169
170 if ( monitor_cache_add( mi, e ) ) {
171 Debug( LDAP_DEBUG_ANY,
172 "monitor_subsys_time_init: "
173 "unable to add entry \"%s,%s\"\n",
174 bv.bv_val, ms->mss_ndn.bv_val );
175 return( -1 );
176 }
177
178 *ep = e;
179 ep = &mp->mp_next;
180
181 monitor_cache_release( mi, e_time );
182
183 return( 0 );
184 }
185
186 static int
monitor_subsys_time_update(Operation * op,SlapReply * rs,Entry * e)187 monitor_subsys_time_update(
188 Operation *op,
189 SlapReply *rs,
190 Entry *e )
191 {
192 monitor_info_t *mi = ( monitor_info_t * )op->o_bd->be_private;
193 static struct berval bv_current = BER_BVC( "cn=current" ),
194 bv_uptime = BER_BVC( "cn=uptime" );
195 struct berval rdn;
196
197 assert( mi != NULL );
198 assert( e != NULL );
199
200 dnRdn( &e->e_nname, &rdn );
201
202 if ( dn_match( &rdn, &bv_current ) ) {
203 struct tm tm;
204 char tmbuf[ LDAP_LUTIL_GENTIME_BUFSIZE ];
205 Attribute *a;
206 ber_len_t len;
207 time_t currtime;
208
209 currtime = slap_get_time();
210
211 ldap_pvt_gmtime( &currtime, &tm );
212 lutil_gentime( tmbuf, sizeof( tmbuf ), &tm );
213
214 len = strlen( tmbuf );
215
216 a = attr_find( e->e_attrs, mi->mi_ad_monitorTimestamp );
217 if ( a == NULL ) {
218 return rs->sr_err = LDAP_OTHER;
219 }
220
221 assert( len == a->a_vals[ 0 ].bv_len );
222 AC_MEMCPY( a->a_vals[ 0 ].bv_val, tmbuf, len );
223
224 /* FIXME: touch modifyTimestamp? */
225
226 } else if ( dn_match( &rdn, &bv_uptime ) ) {
227 Attribute *a;
228 double diff;
229 char buf[ BACKMONITOR_BUFSIZE ];
230 struct berval bv;
231
232 a = attr_find( e->e_attrs, mi->mi_ad_monitoredInfo );
233 if ( a == NULL ) {
234 return rs->sr_err = LDAP_OTHER;
235 }
236
237 diff = difftime( slap_get_time(), starttime );
238 bv.bv_len = snprintf( buf, sizeof( buf ), "%lu",
239 (unsigned long) diff );
240 bv.bv_val = buf;
241
242 ber_bvreplace( &a->a_vals[ 0 ], &bv );
243 if ( a->a_nvals != a->a_vals ) {
244 ber_bvreplace( &a->a_nvals[ 0 ], &bv );
245 }
246
247 /* FIXME: touch modifyTimestamp? */
248 }
249
250 return SLAP_CB_CONTINUE;
251 }
252
253