1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156
|
/* $Id: nws_timeout.c,v 1.4 2003/01/29 05:31:39 graziano Exp $ */
#include "config_nws.h"
#include <stdio.h>
#include <time.h>
#ifdef WITH_LDAP
#include <ldap.h>
#define TWODIGIT_TO_INT(str,pos) ((str[pos]-'0')*10+(str[pos+1]-'0'))
#define FOURDIGIT_TO_INT(str,pos) ((str[pos]-'0')*1000+(str[pos+1]-'0')*100+(str[pos+2]-'0')*10+(str[pos+3]-'0'))
/*
** Simple program that runs once and times out (deletes) any records whose
** expiration is non-zero and whose modifyTimestamp+expiration < time()
** Not terribly well-written, but at least it works
*/
/*
** Same as mktime(3), except that it assumes that timeptr is in UTC, not local
** time.
*/
time_t
mktime_utc(struct tm *timeptr) {
time_t result;
int days;
result = ((timeptr->tm_year-70) * 365 * 24 * 3600); /* Normal years */
result += ((timeptr->tm_year-72)/4 * 24 * 3600); /* Handle leap years */
if (((timeptr->tm_year + 1900) % 4) && (timeptr->tm_mon >= 2))
result += 24 * 3600; /* Handle if this is leap year */
days = 0; /* Handle months; kludge */
switch (timeptr->tm_mon) {
case 11: days += 30;
case 10: days += 31;
case 9: days += 30;
case 8: days += 31;
case 7: days += 31;
case 6: days += 30;
case 5: days += 31;
case 4: days += 30;
case 3: days += 31;
case 2: days += 28;
case 1: days += 31;
}
result += days * 24 * 3600;
result += ((timeptr->tm_mday-1) * 24 * 3600) +
(timeptr->tm_hour * 3600) +
(timeptr->tm_min * 60) +
(timeptr->tm_sec);
return result;
}
/*
** Converts an LDAP timestamp (which follows the syntax of
** 1.3.6.1.4.1.1466.115.121.1.24, generalized time, a string of format
** YYYYMMDDhhmmssZ) to a Unix time value (time_t, seconds since the epoch).
** This function is incomplete: the last character of an LDAP timestamp gives
** the time zone, which we just assume to be Z (UTC).
*/
time_t
ConvertTimeFromLdap(char *ldapTime) {
struct tm t;
/* Convert time to a struct tm */
t.tm_year = FOURDIGIT_TO_INT(ldapTime, 0) - 1900;
t.tm_mon = TWODIGIT_TO_INT (ldapTime, 4) - 1;
t.tm_mday = TWODIGIT_TO_INT (ldapTime, 6);
t.tm_hour = TWODIGIT_TO_INT (ldapTime, 8);
t.tm_min = TWODIGIT_TO_INT (ldapTime, 10);
t.tm_sec = TWODIGIT_TO_INT (ldapTime, 12);
return mktime_utc(&t);
}
int
main (int argc, char **argv) {
int port, result;
LDAP *ld;
LDAPMessage *res, *entry;
const char *attrs[] = {"expiration", "modifyTimestamp", NULL};
char *dn, **rawTimestamp, **rawExpiration;
time_t timestamp, now;
int expiration;
/* Check arguments; get port */
if ((argc != 3) || (sscanf(argv[2], "%i", &port) == 0)) {
printf("Usage: %s ldap_host ldap_port\n", argv[0]);
return 1;
}
/* Initialize LDAP struct */
ld = ldap_init(argv[1], port);
if (ld == NULL) {
perror(argv[0]);
return 1;
}
/* Bind to server */
result = ldap_simple_bind_s(ld, NULL, NULL);
if (result != LDAP_SUCCESS) {
fprintf(stderr, "%s: %s\n", argv[0], ldap_err2string(result));
return 1;
}
/* Get all records that might need deleting */
result = ldap_search_s(ld,
"o=NWS, c=US",
LDAP_SCOPE_SUBTREE,
"(&(expiration=*)(!(expiration=0)))",
(char**) attrs,
0,
&res);
if (result != LDAP_SUCCESS) {
fprintf(stderr, "%s: %s\n", argv[0], ldap_err2string(result));
return 1;
}
entry = ldap_first_entry(ld, res);
now = time(NULL);
while (entry) {
dn = ldap_get_dn(ld, entry);
rawTimestamp = ldap_get_values(ld, entry, "modifyTimestamp");
rawExpiration = ldap_get_values(ld, entry, "expiration");
printf("DN: %s\n", dn);
/*printf(" Timestamp: %s\n", rawTimestamp[0]);*/
/*printf(" Expiration: %s\n", rawExpiration[0]);*/
timestamp = ConvertTimeFromLdap(rawTimestamp[0]);
sscanf(rawExpiration[0], "%i", &expiration);
printf(" Touched: %s", ctime(×tamp));
timestamp += expiration;
printf(" Expires: %s", asctime(localtime(×tamp)));
if (timestamp < now) {
result = ldap_delete_s(ld, dn);
if (result != LDAP_SUCCESS) {
fprintf(stderr, "%s: %s\n", argv[0], ldap_err2string(result));
return 1;
}
printf(" DELETED\n");
}
ldap_value_free(rawTimestamp);
ldap_value_free(rawExpiration);
ldap_memfree(dn);
entry = ldap_next_entry(ld, entry);
}
return 0;
}
#endif
|