Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/crypto/krb5/src/ccapi/lib/ccapi_context_change_time.c
39536 views
1
/* ccapi/lib/ccapi_context_change_time.c */
2
/*
3
* Copyright 2006, 2007 Massachusetts Institute of Technology.
4
* All Rights Reserved.
5
*
6
* Export of this software from the United States of America may
7
* require a specific license from the United States Government.
8
* It is the responsibility of any person or organization contemplating
9
* export to obtain such a license before exporting.
10
*
11
* WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
12
* distribute this software and its documentation for any purpose and
13
* without fee is hereby granted, provided that the above copyright
14
* notice appear in all copies and that both that copyright notice and
15
* this permission notice appear in supporting documentation, and that
16
* the name of M.I.T. not be used in advertising or publicity pertaining
17
* to distribution of the software without specific, written prior
18
* permission. Furthermore if you modify this software you must label
19
* your software as modified software and not distribute it in such a
20
* fashion that it might be confused with the original M.I.T. software.
21
* M.I.T. makes no representations about the suitability of
22
* this software for any purpose. It is provided "as is" without express
23
* or implied warranty.
24
*/
25
26
#include "ccapi_context_change_time.h"
27
#include "cci_common.h"
28
29
#include "k5-thread.h"
30
31
static cci_identifier_t g_change_time_identifer = NULL;
32
static cc_time_t g_change_time = 0;
33
static cc_time_t g_change_time_offset = 0;
34
static k5_mutex_t g_change_time_mutex = K5_MUTEX_PARTIAL_INITIALIZER;
35
36
/* ------------------------------------------------------------------------ */
37
38
cc_int32 cci_context_change_time_thread_init (void)
39
{
40
return k5_mutex_finish_init(&g_change_time_mutex);
41
}
42
43
/* ------------------------------------------------------------------------ */
44
45
void cci_context_change_time_thread_fini (void)
46
{
47
k5_mutex_destroy(&g_change_time_mutex);
48
}
49
50
/* ------------------------------------------------------------------------ */
51
/* WARNING! Mutex must be locked when calling this! */
52
53
static cc_int32 cci_context_change_time_update_identifier (cci_identifier_t in_new_identifier,
54
cc_uint32 *out_server_ids_match,
55
cc_uint32 *out_old_server_running,
56
cc_uint32 *out_new_server_running)
57
{
58
cc_int32 err = ccNoError;
59
cc_uint32 server_ids_match = 0;
60
cc_uint32 old_server_running = 0;
61
cc_uint32 new_server_running = 0;
62
63
if (!in_new_identifier) { err = cci_check_error (err); }
64
65
if (!err && !g_change_time_identifer) {
66
g_change_time_identifer = cci_identifier_uninitialized;
67
}
68
69
if (!err) {
70
err = cci_identifier_compare_server_id (g_change_time_identifer,
71
in_new_identifier,
72
&server_ids_match);
73
}
74
75
if (!err && out_old_server_running) {
76
err = cci_identifier_is_initialized (g_change_time_identifer, &old_server_running);
77
}
78
79
if (!err && out_new_server_running) {
80
err = cci_identifier_is_initialized (in_new_identifier, &new_server_running);
81
}
82
83
if (!err && !server_ids_match) {
84
cci_identifier_t new_change_time_identifer = NULL;
85
86
err = cci_identifier_copy (&new_change_time_identifer, in_new_identifier);
87
88
if (!err) {
89
/* Save the new identifier */
90
if (g_change_time_identifer) {
91
cci_identifier_release (g_change_time_identifer);
92
}
93
g_change_time_identifer = new_change_time_identifer;
94
}
95
}
96
97
if (!err) {
98
if (out_server_ids_match ) { *out_server_ids_match = server_ids_match; }
99
if (out_old_server_running) { *out_old_server_running = old_server_running; }
100
if (out_new_server_running) { *out_new_server_running = new_server_running; }
101
}
102
103
104
return cci_check_error (err);
105
}
106
107
#ifdef TARGET_OS_MAC
108
#pragma mark -
109
#endif
110
111
/* ------------------------------------------------------------------------ */
112
113
cc_int32 cci_context_change_time_get (cc_time_t *out_change_time)
114
{
115
cc_int32 err = ccNoError;
116
117
k5_mutex_lock (&g_change_time_mutex);
118
119
*out_change_time = g_change_time + g_change_time_offset;
120
k5_mutex_unlock (&g_change_time_mutex);
121
122
return err;
123
}
124
125
/* ------------------------------------------------------------------------ */
126
127
cc_int32 cci_context_change_time_update (cci_identifier_t in_identifier,
128
cc_time_t in_new_change_time)
129
{
130
cc_int32 err = ccNoError;
131
k5_mutex_lock (&g_change_time_mutex);
132
133
if (!in_identifier) { err = cci_check_error (err); }
134
135
if (!err) {
136
if (g_change_time < in_new_change_time) {
137
/* Only update if it increases the time. May be a different server. */
138
g_change_time = in_new_change_time;
139
cci_debug_printf ("%s: setting change time to %d",
140
__FUNCTION__, in_new_change_time);
141
}
142
}
143
144
if (!err) {
145
err = cci_context_change_time_update_identifier (in_identifier,
146
NULL, NULL, NULL);
147
}
148
149
k5_mutex_unlock (&g_change_time_mutex);
150
151
return err;
152
}
153
154
/* ------------------------------------------------------------------------ */
155
156
cc_int32 cci_context_change_time_sync (cci_identifier_t in_new_identifier)
157
{
158
cc_int32 err = ccNoError;
159
cc_uint32 server_ids_match = 0;
160
cc_uint32 server_was_running = 0;
161
cc_uint32 server_is_running = 0;
162
163
k5_mutex_lock (&g_change_time_mutex);
164
165
if (!in_new_identifier) { err = cci_check_error (err); }
166
167
if (!err) {
168
err = cci_context_change_time_update_identifier (in_new_identifier,
169
&server_ids_match,
170
&server_was_running,
171
&server_is_running);
172
}
173
174
if (!err && !server_ids_match) {
175
/* Increment the change time so callers re-read */
176
g_change_time_offset++;
177
178
/* If the server died, absorb the offset */
179
if (server_was_running && !server_is_running) {
180
cc_time_t now = time (NULL);
181
182
g_change_time += g_change_time_offset;
183
g_change_time_offset = 0;
184
185
/* Make sure the change time increases, ideally with the current time */
186
g_change_time = (g_change_time < now) ? now : g_change_time;
187
}
188
189
cci_debug_printf ("%s noticed server changed ("
190
"server_was_running = %d; server_is_running = %d; "
191
"g_change_time = %d; g_change_time_offset = %d",
192
__FUNCTION__, server_was_running, server_is_running,
193
g_change_time, g_change_time_offset);
194
}
195
196
k5_mutex_unlock (&g_change_time_mutex);
197
198
return err;
199
}
200
201