xref: /netbsd-src/external/bsd/openldap/dist/servers/slapd/back-monitor/time.c (revision 549b59ed3ccf0d36d3097190a0db27b770f3a839)
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