ReactOS 0.4.15-dev-7788-g1ad9096
auth_time.c File Reference
#include <wintirpc.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <rpc/rpc.h>
#include <rpc/rpc_com.h>
#include <rpc/rpcb_prot.h>
#include <rpcsvc/nis.h>
Include dependency graph for auth_time.c:

Go to the source code of this file.

Macros

#define msg(x)
 
#define NYEARS   (1970 - 1900)
 
#define TOFFSET   ((u_long)60*60*24*(365*NYEARS + (NYEARS/4)))
 

Functions

static void alarm_hndler (int s)
 
static int uaddr_to_sockaddr (char *uaddr, struct sockaddr_in *sin)
 
static void free_eps (eps, int num)
 
static nis_serverget_server (struct sockaddr_in *sin, char *host, nis_server *srv, eps, int maxep)
 
int __rpc_get_time_offset (struct timeval *td, nis_server *srv, char *thost, char **uaddr, struct sockaddr_in *netid)
 

Variables

static int saw_alarm = 0
 

Macro Definition Documentation

◆ msg

#define msg (   x)

Definition at line 54 of file auth_time.c.

◆ NYEARS

#define NYEARS   (1970 - 1900)

Definition at line 73 of file auth_time.c.

◆ TOFFSET

#define TOFFSET   ((u_long)60*60*24*(365*NYEARS + (NYEARS/4)))

Definition at line 74 of file auth_time.c.

Function Documentation

◆ __rpc_get_time_offset()

int __rpc_get_time_offset ( struct timeval td,
nis_server srv,
char thost,
char **  uaddr,
struct sockaddr_in netid 
)

Definition at line 228 of file auth_time.c.

234{
235 CLIENT *clnt; /* Client handle */
236 endpoint *ep, /* useful endpoints */
237 *useep = NULL; /* endpoint of xp */
238 char *useua = NULL; /* uaddr of selected xp */
239 int epl, i; /* counters */
240 enum clnt_stat status; /* result of clnt_call */
241 long thetime;
242 long delta;
243 int needfree = 0;
244 struct timeval tv;
245 int time_valid;
246 int udp_ep = -1, tcp_ep = -1;
247 int a1, a2, a3, a4;
248 char ut[64], ipuaddr[64];
249 endpoint teps[32];
250 nis_server tsrv;
251#ifndef __REACTOS__
252 void (*oldsig)() = NULL; /* old alarm handler */
253#endif
254 struct sockaddr_in sin;
257 int type = 0;
258
259 td->tv_sec = 0;
260 td->tv_usec = 0;
261
262 /*
263 * First check to see if we need to find and address for this
264 * server.
265 */
266 if (*uaddr == NULL) {
267 if ((srv != NULL) && (thost != NULL)) {
268 msg("both timehost and srv pointer used!");
269 return (0);
270 }
271 if (! srv) {
272 srv = get_server(netid, thost, &tsrv, teps, 32);
273 if (srv == NULL) {
274 msg("unable to contruct server data.");
275 return (0);
276 }
277 needfree = 1; /* need to free data in endpoints */
278 }
279
280 ep = srv->ep.ep_val;
281 epl = srv->ep.ep_len;
282
283 /* Identify the TCP and UDP endpoints */
284 for (i = 0;
285 (i < epl) && ((udp_ep == -1) || (tcp_ep == -1)); i++) {
286 if (strcasecmp(ep[i].proto, "udp") == 0)
287 udp_ep = i;
288 if (strcasecmp(ep[i].proto, "tcp") == 0)
289 tcp_ep = i;
290 }
291
292 /* Check to see if it is UDP or TCP */
293 if (tcp_ep > -1) {
294 useep = &ep[tcp_ep];
295 useua = ep[tcp_ep].uaddr;
297 } else if (udp_ep > -1) {
298 useep = &ep[udp_ep];
299 useua = ep[udp_ep].uaddr;
301 }
302
303 if (useep == NULL) {
304 msg("no acceptable transport endpoints.");
305 if (needfree)
306 free_eps(teps, tsrv.ep.ep_len);
307 return (0);
308 }
309 }
310
311 /*
312 * Create a sockaddr from the uaddr.
313 */
314 if (*uaddr != NULL)
315 useua = *uaddr;
316
317 /* Fixup test for NIS+ */
318 sscanf(useua, "%d.%d.%d.%d.", &a1, &a2, &a3, &a4);
319 sprintf(ipuaddr, "%d.%d.%d.%d.0.111", a1, a2, a3, a4);
320 useua = &ipuaddr[0];
321
322 bzero((char *)&sin, sizeof(sin));
323 if (uaddr_to_sockaddr(useua, &sin)) {
324 msg("unable to translate uaddr to sockaddr.");
325 if (needfree)
326 free_eps(teps, tsrv.ep.ep_len);
327 return (0);
328 }
329
330 /*
331 * Create the client handle to rpcbind. Note we always try
332 * version 3 since that is the earliest version that supports
333 * the RPCB_GETTIME call. Also it is the version that comes
334 * standard with SVR4. Since most everyone supports TCP/IP
335 * we could consider trying the rtime call first.
336 */
337 clnt = clnttcp_create(&sin, RPCBPROG, RPCBVERS, &s, 0, 0);
338 if (clnt == NULL) {
339 msg("unable to create client handle to rpcbind.");
340 if (needfree)
341 free_eps(teps, tsrv.ep.ep_len);
342 return (0);
343 }
344
345 tv.tv_sec = 5;
346 tv.tv_usec = 0;
347 time_valid = 0;
349 (xdrproc_t)xdr_u_long, &thetime, tv);
350 /*
351 * The only error we check for is anything but success. In
352 * fact we could have seen PROGMISMATCH if talking to a 4.1
353 * machine (pmap v2) or TIMEDOUT if the net was busy.
354 */
355 if (status == RPC_SUCCESS)
356 time_valid = 1;
357 else {
358 int save;
359
360 /* Blow away possible stale CLNT handle. */
361 if (clnt != NULL) {
362 clnt_destroy(clnt);
363 clnt = NULL;
364 }
365
366 /*
367 * Convert PMAP address into timeservice address
368 * We take advantage of the fact that we "know" what
369 * the universal address looks like for inet transports.
370 *
371 * We also know that the internet timeservice is always
372 * listening on port 37.
373 */
374 sscanf(useua, "%d.%d.%d.%d.", &a1, &a2, &a3, &a4);
375 sprintf(ut, "%d.%d.%d.%d.0.37", a1, a2, a3, a4);
376
377 if (uaddr_to_sockaddr(ut, &sin)) {
378 msg("cannot convert timeservice uaddr to sockaddr.");
379 goto error;
380 }
381
382 s = socket(AF_INET, type, 0);
383 if (s == INVALID_SOCKET) {
384 msg("unable to open fd to network.");
385 goto error;
386 }
387
388 /*
389 * Now depending on whether or not we're talking to
390 * UDP we set a timeout or not.
391 */
392 if (type == SOCK_DGRAM) {
393 struct timeval timeout = { 20, 0 };
394 struct sockaddr_in from;
395 fd_set readfds;
396 int res;
397
398 if (sendto(s, (const char *)&thetime, sizeof(thetime), 0,
399 (struct sockaddr *)&sin, sizeof(sin)) == -1) {
400 msg("udp : sendto failed.");
401 goto error;
402 }
403 do {
404 FD_ZERO(&readfds);
405 FD_SET(s, &readfds);
406 res = select(_rpc_dtablesize(), &readfds,
407 (fd_set *)NULL, (fd_set *)NULL, &timeout);
408 } while (res == SOCKET_ERROR && WSAGetLastError() == WSAEINTR);
409 if (res == SOCKET_ERROR)
410 goto error;
411 len = sizeof(from);
412 res = recvfrom(s, (char *)&thetime, sizeof(thetime), 0,
413 (struct sockaddr *)&from, &len);
414 if (res == SOCKET_ERROR) {
415 msg("recvfrom failed on udp transport.");
416 goto error;
417 }
418 time_valid = 1;
419 } else {
420 int res;
421#ifndef _WIN32
422 oldsig = (void (*)())signal(SIGALRM, alarm_hndler);
423 saw_alarm = 0; /* global tracking the alarm */
424 alarm(20); /* only wait 20 seconds */
425#else
426 saw_alarm = 0;
427 /* XXX Need Windows signal/alarm stuff here XXX */
428#endif
429 res = connect(s, (struct sockaddr *)&sin, sizeof(sin));
430 if (res == SOCKET_ERROR) {
431 msg("failed to connect to tcp endpoint.");
432 goto error;
433 }
434 if (saw_alarm) {
435 msg("alarm caught it, must be unreachable.");
436 goto error;
437 }
438// res = read(s, (char *)&thetime, sizeof(thetime));
439 res = recv(s, (char *)&thetime, sizeof(thetime), 0);
440 if (res != sizeof(thetime)) {
441 if (saw_alarm)
442 msg("timed out TCP call.");
443 else
444 msg("wrong size of results returned");
445
446 goto error;
447 }
448 time_valid = 1;
449 }
450 save = WSAGetLastError();
452 errno = save;
453 s = RPC_ANYSOCK;
454
455 if (time_valid) {
456 thetime = ntohl(thetime);
457 thetime = thetime - TOFFSET; /* adjust to UNIX time */
458 } else
459 thetime = 0;
460 }
461
462 gettimeofday(&tv, 0);
463
464error:
465 /*
466 * clean up our allocated data structures.
467 */
468
469 if (s != RPC_ANYSOCK)
471
472 if (clnt != NULL)
473 clnt_destroy(clnt);
474
475#ifdef _WIN32
476 /* XXX Need Windows signal/alarm stuff here XXX */
477#else
478 alarm(0); /* reset that alarm if its outstanding */
479 if (oldsig) {
480 signal(SIGALRM, oldsig);
481 }
482#endif
483
484 /*
485 * note, don't free uaddr strings until after we've made a
486 * copy of them.
487 */
488 if (time_valid) {
489 if (*uaddr == NULL)
490 *uaddr = strdup(useua);
491
492 /* Round to the nearest second */
493 tv.tv_sec += (tv.tv_sec > 500000) ? 1 : 0;
494 delta = (thetime > tv.tv_sec) ? thetime - tv.tv_sec :
495 tv.tv_sec - thetime;
496 td->tv_sec = (thetime < tv.tv_sec) ? - delta : delta;
497 td->tv_usec = 0;
498 } else {
499 msg("unable to get the server's time.");
500 }
501
502 if (needfree)
503 free_eps(teps, tsrv.ep.ep_len);
504
505 return (time_valid);
506}
bool_t xdr_void(void)
Definition: xdr.c:92
bool_t xdr_u_long(XDR *xdrs, u_long *ulp)
Definition: xdr.c:186
_STLP_DECLSPEC complex< float > _STLP_CALL sin(const complex< float > &)
#define gettimeofday(tv, tz)
Definition: adns_win32.h:159
static nis_server * get_server(struct sockaddr_in *sin, char *host, nis_server *srv, eps, int maxep)
Definition: auth_time.c:143
#define TOFFSET
Definition: auth_time.c:74
static void alarm_hndler(int s)
Definition: auth_time.c:60
static void free_eps(eps, int num)
Definition: auth_time.c:117
static int uaddr_to_sockaddr(char *uaddr, struct sockaddr_in *sin)
Definition: auth_time.c:82
#define msg(x)
Definition: auth_time.c:54
static int saw_alarm
Definition: auth_time.c:57
#define bzero(s, n)
Definition: various.h:27
#define clnt_destroy(rh)
Definition: clnt.h:276
#define clnt_call(rh, proc, xargs, argsp, xres, resp, secs)
Definition: clnt.h:202
__BEGIN_DECLS CLIENT * clnttcp_create(struct sockaddr_in *, u_long, u_long, SOCKET *, u_int, u_int)
clnt_stat
Definition: clnt_stat.h:21
@ RPC_SUCCESS
Definition: clnt_stat.h:22
#define RPC_ANYSOCK
Definition: svc.h:327
#define NULL
Definition: types.h:112
INT WSAAPI recvfrom(IN SOCKET s, OUT CHAR FAR *buf, IN INT len, IN INT flags, OUT LPSOCKADDR from, IN OUT INT FAR *fromlen)
Definition: recv.c:87
INT WSAAPI recv(IN SOCKET s, OUT CHAR FAR *buf, IN INT len, IN INT flags)
Definition: recv.c:23
INT WSAAPI select(IN INT s, IN OUT LPFD_SET readfds, IN OUT LPFD_SET writefds, IN OUT LPFD_SET exceptfds, IN CONST struct timeval *timeout)
Definition: select.c:41
INT WSAAPI sendto(IN SOCKET s, IN CONST CHAR FAR *buf, IN INT len, IN INT flags, IN CONST struct sockaddr *to, IN INT tolen)
Definition: send.c:82
#define SOCK_STREAM
Definition: tcpip.h:118
#define AF_INET
Definition: tcpip.h:117
#define strcasecmp
Definition: fake.h:9
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
GLdouble s
Definition: gl.h:2039
GLuint res
Definition: glext.h:9613
GLenum GLsizei len
Definition: glext.h:6722
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
_Check_return_ _CRTIMP int __cdecl sscanf(_In_z_ const char *_Src, _In_z_ _Scanf_format_string_ const char *_Format,...)
#define error(str)
Definition: mkdosfs.c:1605
#define ntohl(x)
Definition: module.h:205
int socklen_t
Definition: tcp.c:35
#define sprintf(buf, format,...)
Definition: sprintf.c:55
static const struct update_accum a1
Definition: msg.c:578
static const struct update_accum a2
Definition: msg.c:586
static const struct update_accum a3
Definition: msg.c:600
static const struct update_accum a4
Definition: msg.c:2285
#define closesocket
Definition: ncftp.h:477
int _rpc_dtablesize(void)
#define RPCBPROG
Definition: rpcb_prot.h:626
#define RPCBPROC_GETTIME
Definition: rpcb_prot.h:697
#define RPCBVERS
Definition: rpcb_prot.h:627
#define errno
Definition: errno.h:18
_Check_return_ _CRTIMP char *__cdecl strdup(_In_opt_z_ const char *_Src)
int signal
Definition: except.c:82
SOCKET WSAAPI socket(IN INT af, IN INT type, IN INT protocol)
Definition: socklife.c:143
CardRegion * from
Definition: spigame.cpp:19
Definition: nis.h:10
char * uaddr
Definition: nis.h:11
Definition: winsock.h:66
Definition: nis.h:17
struct nis_server::@213 ep
Definition: ps.c:97
Definition: dhcpd.h:245
unsigned long tv_sec
Definition: linux.h:1738
unsigned long tv_usec
Definition: linux.h:1739
#define WSAEINTR
Definition: winerror.h:1942
int PASCAL FAR WSAGetLastError(void)
Definition: dllmain.c:112
#define FD_ZERO(set)
Definition: winsock.h:96
#define INVALID_SOCKET
Definition: winsock.h:332
#define SOCK_DGRAM
Definition: winsock.h:336
UINT_PTR SOCKET
Definition: winsock.h:47
#define SOCKET_ERROR
Definition: winsock.h:333
#define FD_SET(fd, set)
Definition: winsock.h:89
bool_t(* xdrproc_t)(XDR *,...)
Definition: xdr.h:144

◆ alarm_hndler()

static void alarm_hndler ( int  s)
static

Definition at line 60 of file auth_time.c.

62{
63 saw_alarm = 1;
64 return;
65}

Referenced by __rpc_get_time_offset().

◆ free_eps()

static void free_eps ( eps  ,
int  num 
)
static

Definition at line 117 of file auth_time.c.

120{
121 int i;
122
123 for (i = 0; i < num; i++) {
124 free(eps[i].uaddr);
125 free(eps[i].proto);
126 free(eps[i].family);
127 }
128 return;
129}
#define free
Definition: debug_ros.c:5
GLuint GLuint num
Definition: glext.h:9618
#define eps

Referenced by __rpc_get_time_offset().

◆ get_server()

static nis_server * get_server ( struct sockaddr_in sin,
char host,
nis_server srv,
eps  ,
int  maxep 
)
static

Definition at line 143 of file auth_time.c.

149{
150 char hname[256];
151 int num_ep = 0, i;
152 struct hostent *he;
153 struct hostent dummy;
154 char *ptr[2];
155
156 if (host == NULL && sin == NULL)
157 return (NULL);
158
159 if (sin == NULL) {
160 he = gethostbyname(host);
161 if (he == NULL)
162 return(NULL);
163 } else {
164 he = &dummy;
165 ptr[0] = (char *)&sin->sin_addr.s_addr;
166 ptr[1] = NULL;
167 dummy.h_addr_list = ptr;
168 }
169
170 /*
171 * This is lame. We go around once for TCP, then again
172 * for UDP.
173 */
174 for (i = 0; (he->h_addr_list[i] != NULL) && (num_ep < maxep);
175 i++, num_ep++) {
176 struct in_addr *a;
177
178 a = (struct in_addr *)he->h_addr_list[i];
179 snprintf(hname, sizeof(hname), "%s.0.111", inet_ntoa(*a));
180 eps[num_ep].uaddr = strdup(hname);
181 eps[num_ep].family = strdup("inet");
182 eps[num_ep].proto = strdup("tcp");
183 }
184
185 for (i = 0; (he->h_addr_list[i] != NULL) && (num_ep < maxep);
186 i++, num_ep++) {
187 struct in_addr *a;
188
189 a = (struct in_addr *)he->h_addr_list[i];
190 snprintf(hname, sizeof(hname), "%s.0.111", inet_ntoa(*a));
191 eps[num_ep].uaddr = strdup(hname);
192 eps[num_ep].family = strdup("inet");
193 eps[num_ep].proto = strdup("udp");
194 }
195
196 srv->name = (nis_name) host;
197 srv->ep.ep_len = num_ep;
198 srv->ep.ep_val = eps;
199 srv->key_type = NIS_PK_NONE;
200 srv->pkey.n_bytes = NULL;
201 srv->pkey.n_len = 0;
202 return (srv);
203}
PHOSTENT WSAAPI gethostbyname(IN const char FAR *name)
Definition: getxbyxx.c:221
GLboolean GLboolean GLboolean GLboolean a
Definition: glext.h:6204
#define inet_ntoa(addr)
Definition: inet.h:100
#define a
Definition: ke_i.h:78
static PVOID ptr
Definition: dispmode.c:27
char * nis_name
Definition: nis.h:9
#define NIS_PK_NONE
Definition: nis.h:4
char ** h_addr_list
Definition: winsock.h:138
Definition: tcpip.h:126
u_int n_len
Definition: xdr.h:333
char * n_bytes
Definition: xdr.h:334
uint32_t key_type
Definition: nis.h:23
netobj pkey
Definition: nis.h:24
nis_name name
Definition: nis.h:18
char * host
Definition: whois.c:55
#define snprintf
Definition: wintirpc.h:48

Referenced by __rpc_get_time_offset(), and InternetGetSecurityInfoByURLW().

◆ uaddr_to_sockaddr()

static int uaddr_to_sockaddr ( char uaddr,
struct sockaddr_in sin 
)
static

Definition at line 82 of file auth_time.c.

88{
89 unsigned char p_bytes[2];
90 int i;
91 unsigned long a[6];
92
93 i = sscanf(uaddr, "%lu.%lu.%lu.%lu.%lu.%lu", &a[0], &a[1], &a[2],
94 &a[3], &a[4], &a[5]);
95
96 if (i < 6)
97 return(1);
98
99 for (i = 0; i < 4; i++)
100 sin->sin_addr.s_addr |= (a[i] & 0x000000FF) << (8 * i);
101
102 p_bytes[0] = (unsigned char)a[4] & 0x000000FF;
103 p_bytes[1] = (unsigned char)a[5] & 0x000000FF;
104
105 sin->sin_family = AF_INET; /* always */
106 bcopy((char *)&p_bytes, (char *)&sin->sin_port, 2);
107
108 return (0);
109}
#define bcopy(s1, s2, n)
Definition: various.h:25
unsigned char
Definition: typeof.h:29

Referenced by __rpc_get_time_offset().

Variable Documentation

◆ saw_alarm

int saw_alarm = 0
static

Definition at line 57 of file auth_time.c.

Referenced by __rpc_get_time_offset(), and alarm_hndler().