summaryrefslogtreecommitdiffstats
path: root/ldap/servers/slapd/slap.h
blob: abccf3ad58b4701912143cb125aa94254e476d7f (plain)
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
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
/** BEGIN COPYRIGHT BLOCK
 * This Program is free software; you can redistribute it and/or modify it under
 * the terms of the GNU General Public License as published by the Free Software
 * Foundation; version 2 of the License.
 * 
 * This Program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License along with
 * this Program; if not, write to the Free Software Foundation, Inc., 59 Temple
 * Place, Suite 330, Boston, MA 02111-1307 USA.
 * 
 * In addition, as a special exception, Red Hat, Inc. gives You the additional
 * right to link the code of this Program with code not covered under the GNU
 * General Public License ("Non-GPL Code") and to distribute linked combinations
 * including the two, subject to the limitations in this paragraph. Non-GPL Code
 * permitted under this exception must only link to the code of this Program
 * through those well defined interfaces identified in the file named EXCEPTION
 * found in the source code files (the "Approved Interfaces"). The files of
 * Non-GPL Code may instantiate templates or use macros or inline functions from
 * the Approved Interfaces without causing the resulting work to be covered by
 * the GNU General Public License. Only Red Hat, Inc. may make changes or
 * additions to the list of Approved Interfaces. You must obey the GNU General
 * Public License in all respects for all of the Program code and other code used
 * in conjunction with the Program except the Non-GPL Code covered by this
 * exception. If you modify this file, you may extend this exception to your
 * version of the file, but you are not obligated to do so. If you do not wish to
 * provide this exception without modification, you must delete this exception
 * statement from your version and license this file solely under the GPL without
 * exception. 
 * 
 * 
 * Copyright (C) 2001 Sun Microsystems, Inc. Used by permission.
 * Copyright (C) 2005 Red Hat, Inc.
 * All rights reserved.
 * END COPYRIGHT BLOCK **/

#ifdef HAVE_CONFIG_H
#  include <config.h>
#endif

/* slap.h - stand alone ldap server include file */

#ifndef _SLDAPD_H_
#define _SLDAPD_H_

 
/* Used by SSL and DES plugin */
#ifdef NEED_TOK_DES
static char  tokDes[34] = "Communicator Generic Crypto Svcs";
static char ptokDes[34] = "Internal (Software) Token        ";
#endif

/*
 * The slapd executable can function in on of several modes.
 */
#define SLAPD_EXEMODE_UNKNOWN		0
#define SLAPD_EXEMODE_SLAPD		1
#define SLAPD_EXEMODE_DB2LDIF		2
#define SLAPD_EXEMODE_LDIF2DB		3
#define SLAPD_EXEMODE_DB2ARCHIVE	4
#define SLAPD_EXEMODE_ARCHIVE2DB	5
#define SLAPD_EXEMODE_DBTEST		6
#define SLAPD_EXEMODE_DB2INDEX		7
#define SLAPD_EXEMODE_REFERRAL		8
#define SLAPD_EXEMODE_SUFFIX2INSTANCE	9
#define SLAPD_EXEMODE_PRINTVERSION  10
#define SLAPD_EXEMODE_UPGRADEDB     11
#define SLAPD_EXEMODE_DBVERIFY      12

#ifdef _WIN32
#ifndef DONT_DECLARE_SLAPD_LDAP_DEBUG
extern __declspec(dllimport) int	slapd_ldap_debug;	/* XXXmcs: should eliminate this */
#endif /* DONT_DECLARE_SLAPD_LDAP_DEBUG */
typedef char *caddr_t;
void *dlsym(void *a, char *b);
#define LOG_PID		0x01
#define LOG_NOWAIT	0x10
#define LOG_DEBUG	7
#define POLL_STRUCT PRPollDesc
#define POLL_FN PR_Poll
#define RLIM_TYPE  int
#else /* _WIN32 */
#define LDAP_SYSLOG
#include <syslog.h>
#define RLIM_TYPE int
#include <poll.h>
#define POLL_STRUCT PRPollDesc
#define POLL_FN PR_Poll
#endif /* _WIN32 */

#include <stdio.h>  /* for FILE */
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <errno.h>
#if defined(SOLARIS)
#include <limits.h> /* for LONG_MAX */
#endif

/* there's a bug in the dbm code we import (from where?) -- FIXME */
#ifdef LINUX
#define LITTLE_ENDIAN __LITTLE_ENDIAN
#endif
#include <cert.h> 

#ifndef _WIN32
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <netinet/in.h>
#endif /* _WIN32 */

#ifdef _WIN32
#define LDAP_IOCP
#endif

#define LOG_INTERNAL_OP_CON_ID      "Internal"
#define LOG_INTERNAL_OP_OP_ID       -1

#define MAX_SERVICE_NAME 25

#define SLAPD_TYPICAL_ATTRIBUTE_NAME_MAX_LENGTH 256

typedef struct symbol_t {
    const char* name;
    unsigned number;
} symbol_t;

#define SLAPD_SSLCLIENTAUTH_OFF      0
#define SLAPD_SSLCLIENTAUTH_ALLOWED  1 /* server asks for cert, but client need not send one */
#define SLAPD_SSLCLIENTAUTH_REQUIRED 2 /* server will refuse SSL session unless client sends cert */
#define SLAPD_SSLCLIENTAUTH_DEFAULT  SLAPD_SSLCLIENTAUTH_ALLOWED

#define	SLAPD_LOGGING	1
#define NUM_SNMP_INT_TBL_ROWS 5

/* include NSPR header files */
#include "nspr.h"
#include "plhash.h"

/* include NSS header files */
#include "ssl.h"

#include <sys/types.h> /* this should be moved into avl.h */

#include "avl.h"
#include "ldap.h"
#include "ldaprot.h"
#include "ldif.h"
#include "ldaplog.h"
#include "portable.h"
#include "rwlock.h"
#include "litekey.h"
#include "disconnect_errors.h"

#include "dirver.h"
#include "csngen.h"
#include "uuid.h"

#if defined(OS_solaris)
#  include <thread.h>
#  define GET_THREAD_ID() thr_self()
#else 
#  if defined(_WIN32)
#    define GET_THREAD_ID() GetCurrentThreadId()
#  else
#    include <pthread.h>
#    define GET_THREAD_ID() pthread_self()
#  endif
#endif


/*
 * XXXmcs: these are defined by ldap.h or ldap-extension.h,
 * but only in a newer release than we use with DS today.
 */
#ifndef LDAP_CONTROL_AUTH_REQUEST
#define LDAP_CONTROL_AUTH_REQUEST	"2.16.840.1.113730.3.4.16"
#endif
#ifndef LDAP_CONTROL_AUTH_RESPONSE
#define LDAP_CONTROL_AUTH_RESPONSE	"2.16.840.1.113730.3.4.15"
#endif
#ifndef LDAP_CONTROL_REAL_ATTRS_ONLY
#define LDAP_CONTROL_REAL_ATTRS_ONLY	"2.16.840.1.113730.3.4.17"
#endif
#ifndef LDAP_CONTROL_VIRT_ATTRS_ONLY
#define LDAP_CONTROL_VIRT_ATTRS_ONLY	"2.16.840.1.113730.3.4.19"
#endif
#ifndef LDAP_CONTROL_GET_EFFECTIVE_RIGHTS
#define LDAP_CONTROL_GET_EFFECTIVE_RIGHTS "1.3.6.1.4.1.42.2.27.9.5.2"
#endif

#define SLAPD_VENDOR_NAME	"Fedora Project"
#define SLAPD_VERSION_STR	"Fedora-Directory/" PRODUCTTEXT
#define SLAPD_SHORT_VERSION_STR	PRODUCTTEXT

typedef void	(*VFP)(void *);
typedef void	(*VFP0)();
#define LDAPI_INTERNAL	1
#include "slapi-private.h"
#include "pw.h"
/*
 * call the appropriate signal() function.
 */
#if ( defined( hpux ) || defined ( irix ))
/* 
 * we should not mix POSIX signal library function (sigaction)
 * with SYSV's (sigset) on IRIX.  nspr uses POSIX internally.
 */
#define SIGNAL( s, a ) signal2sigaction( s, (void *) a )
#elif ( defined( SYSV ) || defined( aix ))
#define SIGNAL sigset
#else
#define SIGNAL signal
#endif

/*
 * SLAPD_PR_WOULD_BLOCK_ERROR() returns non-zero if prerrno is an NSPR
 *	error code that indicates a temporary non-blocking I/O error,
 *	e.g., PR_WOULD_BLOCK_ERROR.
 */
#define SLAPD_PR_WOULD_BLOCK_ERROR( prerrno )	\
	((prerrno) == PR_WOULD_BLOCK_ERROR || (prerrno) == PR_IO_TIMEOUT_ERROR)

/*
 * SLAPD_SYSTEM_WOULD_BLOCK_ERROR() returns non-zero if syserrno is an OS
 *	error code that indicates a temporary non-blocking I/O error,
 *	e.g., EAGAIN.
 */
#define SLAPD_SYSTEM_WOULD_BLOCK_ERROR( syserrno )	\
	((syserrno)==EAGAIN || (syserrno)==EWOULDBLOCK)


#define LDAP_ON		1
#define LDAP_OFF	0
#define LDAP_UNDEFINED (-1)

#ifndef SLAPD_INVALID_SOCKET
#ifdef _WIN32
#define SLAPD_INVALID_SOCKET	0
#else
#define SLAPD_INVALID_SOCKET	0
#endif
#endif

#define SLAPD_INVALID_SOCKET_INDEX	(-1)

#ifdef _WIN32
#define SLAPD_DEFAULT_FILE_MODE				S_IREAD | S_IWRITE
#define SLAPD_DEFAULT_DIR_MODE  			0
#else /* _WIN32 */
#define SLAPD_DEFAULT_FILE_MODE				S_IRUSR | S_IWUSR
#define SLAPD_DEFAULT_DIR_MODE				S_IRWXU
#endif

#define SLAPD_DEFAULT_IDLE_TIMEOUT			0		/* seconds - 0 == never */
#define SLAPD_DEFAULT_SIZELIMIT				2000	/* use -1 for no limit */
#define SLAPD_DEFAULT_TIMELIMIT				3600	/* use -1 for no limit */
#define SLAPD_DEFAULT_LOOKTHROUGHLIMIT		5000	/* use -1 for no limit */
#define SLAPD_DEFAULT_GROUPNESTLEVEL		5
#define SLAPD_DEFAULT_MAX_FILTER_NEST_LEVEL	40		/* use -1 for no limit */
#define SLAPD_DEFAULT_IOBLOCK_TIMEOUT		1800000 /* half hour in ms */
#define SLAPD_DEFAULT_OUTBOUND_LDAP_IO_TIMEOUT	300000 /* 5 minutes in ms */
#define SLAPD_DEFAULT_RESERVE_FDS			64
#define SLAPD_DEFAULT_MAX_THREADS			30		/* connection pool threads */
#define SLAPD_DEFAULT_MAX_THREADS_PER_CONN	5		/* allowed per connection */
#define SLAPD_DEFAULT_SCHEMA_IGNORE_TRAILING_SPACES	LDAP_OFF

							/* We'd like this number to be prime for 
							    the hash into the Connection table */
#define SLAPD_DEFAULT_CONNTABLESIZE		4093	/* connection table size */

#define SLAPD_MONITOR_DN		"cn=monitor"
#define SLAPD_SCHEMA_DN			"cn=schema"
#define SLAPD_CONFIG_DN			"cn=config"

#define EGG_OBJECT_CLASS		"directory~team~extensible~object"
#define EGG_FILTER				"(objectclass=directory~team~extensible~object)"

#define BE_LIST_SIZE 100 /* used by mapping tree code to hold be_list stuff */

#define	REPL_DBTYPE		"ldbm"
#define	REPL_DBTAG		"repl"

#define ATTR_NETSCAPEMDSUFFIX "netscapemdsuffix"

/* Used to make unhashed passwords available to plugins. */
#define	PSEUDO_ATTR_UNHASHEDUSERPASSWORD	"unhashed#user#password"

#define REFERRAL_REMOVE_CMD "remove"

/* Filenames for DSE storage */
#define	DSE_FILENAME	"dse.ldif"
#define	DSE_TMPFILE	"dse.ldif.tmp"
#define	DSE_BACKFILE	"dse.ldif.bak"
#define	DSE_STARTOKFILE	"dse.ldif.startOK"
#define DSE_LDBM_FILENAME "ldbm.ldif"
#define DSE_LDBM_TMPFILE "ldbm.ldif.tmp"
/* for now, we are using the dse file for the base config file */
#define CONFIG_FILENAME DSE_FILENAME
/* the default configuration sub directory of the instance directory */
#define CONFIG_SUBDIR_NAME "config"
/* the default schema sub directory of the config sub directory */
#define SCHEMA_SUBDIR_NAME "schema"

/* LDAPI default configuration */
#define SLAPD_LDAPI_DEFAULT_FILENAME "/var/run/ldapi"
#define SLAPD_LDAPI_DEFAULT_STATUS "off"

struct subfilt {
	char	*sf_type;
	char	*sf_initial;
	char	**sf_any;
	char	*sf_final;
	void	*sf_private;	/* data private to syntax handler */
};

#include "filter.h" /* mr_filter_t */

/*
 * represents a search filter
 */
struct slapi_filter {
	int f_flags;
	unsigned long	f_choice;	/* values taken from ldap.h */
	PRUint32	f_hash;		/* for quick comparisons */
	void *assigned_decoder;

	union {
		/* present */
		char		*f_un_type;

		/* equality, lessorequal, greaterorequal, approx */
		struct ava	f_un_ava;

		/* and, or, not */
		struct slapi_filter	*f_un_complex;

		/* substrings */
		struct subfilt	f_un_sub;

		/* extended -- v3 only */
		mr_filter_t	f_un_extended;
	} f_un;
#define f_type		f_un.f_un_type
#define f_ava		f_un.f_un_ava
#define f_avtype	f_un.f_un_ava.ava_type
#define f_avvalue	f_un.f_un_ava.ava_value
#define f_and		f_un.f_un_complex
#define f_or		f_un.f_un_complex
#define f_not		f_un.f_un_complex
#define f_list		f_un.f_un_complex
#define f_sub		f_un.f_un_sub
#define f_sub_type	f_un.f_un_sub.sf_type
#define f_sub_initial	f_un.f_un_sub.sf_initial
#define f_sub_any	f_un.f_un_sub.sf_any
#define f_sub_final	f_un.f_un_sub.sf_final
#define f_mr		f_un.f_un_extended
#define f_mr_oid	f_un.f_un_extended.mrf_oid
#define f_mr_type	f_un.f_un_extended.mrf_type
#define f_mr_value	f_un.f_un_extended.mrf_value
#define f_mr_dnAttrs	f_un.f_un_extended.mrf_dnAttrs

	struct slapi_filter	*f_next;
};

struct csn
{
    time_t tstamp;
    PRUint16 seqnum;
    ReplicaId rid;
	PRUint16 subseqnum;
};

struct csnset_node
{
	CSNType type;
	CSN csn;
	CSNSet *next;
};

struct slapi_value
{
    struct berval bv;
    CSNSet *v_csnset;
    unsigned long v_flags;
};

/*
 * JCM: This structure, slapi_value_set, seems useless,
 * but in the future we could:
 *
 *	{
 *	unsigned char flag;
 *	union single
 *	{
 *		struct slapi_value *va;
 *	};
 *	union multiple_array
 *	{
 *		short num;
 *		short max;
 *		struct slapi_value **va;
 *	};
 *	union multiple_tree
 *	{
 *		struct slapi_value_tree *vt;
 *	};
 */
struct slapi_value_set
{
	struct slapi_value **va;
};

struct valuearrayfast
{
	int num; /* The number of values in the array */
	int max; /* The number of slots in the array */
	struct slapi_value **va;
};

struct bervals2free {
    struct berval **bvals;
    struct bervals2free *next;
};

/*
 * represents an attribute instance (type + values + syntax)
 */

struct slapi_attr {
	char					*a_type;
	struct slapi_value_set  a_present_values;
	unsigned long		    a_flags;		/* SLAPI_ATTR_FLAG_... */
	struct slapdplugin	    *a_plugin;
	struct slapi_value_set  a_deleted_values;
	struct bervals2free     *a_listtofree; /* JCM: EVIL... For DS4 Slapi compatibility. */
	struct slapi_attr		*a_next;
	CSN                     *a_deletioncsn; /* The point in time at which this attribute was last deleted */
};

typedef struct oid_item {
    char *oi_oid;
    struct slapdplugin	*oi_plugin;
    struct oid_item	*oi_next;
} oid_item_t;

/* attribute description (represents an attribute, but not the value) */
typedef struct asyntaxinfo {
    char    			*asi_oid;			/* OID */
	char				*asi_name;			/* normalized name */
	char				**asi_aliases;		/* alternative names */
    char    			*asi_desc;			/* textual description */
	char				*asi_superior;		/* derived from */
	char				*asi_mr_equality;	/* equality matching rule */
	char				*asi_mr_ordering;	/* ordering matching rule */
	char				*asi_mr_substring;	/* substring matching rule */
	char				**asi_origin;		/* X-ORIGIN extension */
	struct slapdplugin	*asi_plugin;		/* syntax */
	unsigned long		asi_flags;			/* SLAPI_ATTR_FLAG_... */
	int					asi_syntaxlength;	/* length associated w/syntax */
	int					asi_refcnt;			/* outstanding references */
	PRBool				asi_marked_for_delete;	/* delete at next opportunity */
} asyntaxinfo;

/*
 * Note: most of the asi_flags values are defined in slapi-plugin.h, but
 * these ones are private to the DS.
 */
#define SLAPI_ATTR_FLAG_OVERRIDE	0x0010	/* when adding a new attribute,
											   override the existing attribute,
											   if any */
#define SLAPI_ATTR_FLAG_NOLOCKING	0x0020	/* the init code doesn't lock the
											   tables */
#define SLAPI_ATTR_FLAG_CMP_BITBYBIT	0x4000	/* do memcmp, not syntax cmp */
#define SLAPI_ATTR_FLAG_KEEP		0x8000 /* keep when replacing all */

/* This is the type of the function passed into attr_syntax_enumerate_attrs */
typedef int (*AttrEnumFunc)(struct asyntaxinfo *asi, void *arg);
/* Possible return values for an AttrEnumFunc */
#define ATTR_SYNTAX_ENUM_NEXT	0	/* continue */
#define ATTR_SYNTAX_ENUM_STOP	1	/* halt the enumeration */
#define ATTR_SYNTAX_ENUM_REMOVE	2	/* unhash current node and continue */

/* This is the type of the function passed into plugin_syntax_enumerate */
typedef int (*SyntaxEnumFunc)(char **names, Slapi_PluginDesc *plugindesc,
							void *arg);

/* OIDs for some commonly used syntaxes */
#define BINARY_SYNTAX_OID    		"1.3.6.1.4.1.1466.115.121.1.5"
#define BOOLEAN_SYNTAX_OID			"1.3.6.1.4.1.1466.115.121.1.7"
#define COUNTRYSTRING_SYNTAX_OID	"1.3.6.1.4.1.1466.115.121.1.11"
#define DN_SYNTAX_OID        		"1.3.6.1.4.1.1466.115.121.1.12"
#define DIRSTRING_SYNTAX_OID		"1.3.6.1.4.1.1466.115.121.1.15"
#define GENERALIZEDTIME_SYNTAX_OID	"1.3.6.1.4.1.1466.115.121.1.24"
#define IA5STRING_SYNTAX_OID		"1.3.6.1.4.1.1466.115.121.1.26"
#define INTEGER_SYNTAX_OID   		"1.3.6.1.4.1.1466.115.121.1.27"
#define JPEG_SYNTAX_OID				"1.3.6.1.4.1.1466.115.121.1.28"
#define OCTETSTRING_SYNTAX_OID		"1.3.6.1.4.1.1466.115.121.1.40"
#define OID_SYNTAX_OID				"1.3.6.1.4.1.1466.115.121.1.38"
#define POSTALADDRESS_SYNTAX_OID	"1.3.6.1.4.1.1466.115.121.1.41"
#define TELEPHONE_SYNTAX_OID		"1.3.6.1.4.1.1466.115.121.1.50"
#define SPACE_INSENSITIVE_STRING_SYNTAX_OID	"2.16.840.1.113730.3.7.1"

/* OIDs for some commonly used matching rules */
#define DNMATCH_OID				"2.5.13.1"	/* distinguishedNameMatch */
#define CASEIGNOREMATCH_OID		"2.5.13.2"	/* caseIgnoreMatch */
#define INTFIRSTCOMPMATCH_OID	"2.5.13.29"	/* integerFirstComponentMatch */
#define OIDFIRSTCOMPMATCH_OID	"2.5.13.30"	/* objectIdentifierFirstComponentMatch */

/* Names for some commonly used matching rules */
#define DNMATCH_NAME			"distinguishedNameMatch"
#define CASEIGNOREMATCH_NAME	"caseIgnoreMatch"
#define INTFIRSTCOMPMATCH_NAME	"integerFirstComponentMatch"
#define OIDFIRSTCOMPMATCH_NAME	"objectIdentifierFirstComponentMatch"

#define ATTR_STANDARD_STRING	"Standard Attribute"
#define ATTR_USERDEF_STRING		"User Defined Attribute"
#define OC_STANDARD_STRING		"Standard ObjectClass"
#define OC_USERDEF_STRING		"User Defined ObjectClass"

/* modifiers used to define attributes */
#define ATTR_MOD_OPERATIONAL "operational"
#define ATTR_MOD_OVERRIDE    "override"
#define ATTR_MOD_SINGLE      "single"

/* extended operations supported by the server */
#define EXTOP_BULK_IMPORT_START_OID     "2.16.840.1.113730.3.5.7"
#define EXTOP_BULK_IMPORT_DONE_OID      "2.16.840.1.113730.3.5.8"

/* 
 * Represents a Distinguished Name of an entry
 * WARNING, if you change this stucture you MUST update dn_size()
 * function in entry.c
 */
struct slapi_dn
{
    unsigned char flag;
    const char *dn; /* DN */
    const char *ndn; /* Case Normalised DN */
    int ndn_len; /* normalize dn len */
};

/* 
 * Represents a Relative Distinguished Name.
 */

struct slapi_rdn
{
    unsigned char flag;
	char *rdn;
	char **rdns; /* Valid when FLAG_RDNS is set. */
	int butcheredupto; /* How far through rdns we've gone converting '=' to '\0' */
};

/* 
 * representation of uniqueID. Defined in uuid.h
 */
#define UID_SIZE 16	/* size of unique id in bytes */

/*
 * max 1G attr values per entry
 * in case, libdb returned bogus entry string from db (blackflag #623569)
 */
#define ENTRY_MAX_ATTRIBUTE_VALUE_COUNT 1073741824 

/*
 * represents an entry in core
 * WARNING, if you change this stucture you MUST update slapi_entry_size()
 * function
 */
struct slapi_entry {
    struct slapi_dn e_sdn;		/* DN of this entry */
    char *e_uniqueid;   /* uniqueID of this entry */
    CSNSet *e_dncsnset;      /* The set of DN CSNs for this entry */
	CSN *e_maxcsn;			/* maximum CSN of the entry */
    Slapi_Attr *e_attrs;	/* list of attributes and values   */
    Slapi_Attr *e_deleted_attrs; /* deleted list of attributes and values */
	Slapi_Attr *e_virtual_attrs; /* list of virtual attributes */
    time_t e_virtual_watermark; /* indicates cache consistency when compared to global watermark */ 
    PRRWLock *e_virtual_lock; /* for access to cached vattrs */
	void *e_extension;          /* A list of entry object extensions */
	unsigned char e_flags;
};

/*
 * represents schema information for a database
 */
/* values for oc_flags (only space for 8 of these right now!) */
#define OC_FLAG_STANDARD_OC		1
#define OC_FLAG_USER_OC			2
#define OC_FLAG_REDEFINED_OC	4
#define OC_FLAG_OBSOLETE		8

/* values for oc_kind */
#define OC_KIND_STRUCTURAL		0
#define OC_KIND_AUXILIARY		1
#define OC_KIND_ABSTRACT		2


/* XXXmcs: ../plugins/cos/cos_cache.c has its own copy of this definition! */
struct objclass {
	char				*oc_name;		/* NAME */
	char				*oc_desc;		/* DESC */
    char        		*oc_oid;		/* object identifier */
    char        		*oc_superior;	/* SUP -- XXXmcs: should be an array */
	PRUint8				oc_kind;		/* ABSTRACT/STRUCTURAL/AUXILIARY */
    PRUint8				oc_flags;		/* misc. flags, e.g., OBSOLETE */
	char				**oc_required;
	char				**oc_allowed;
    char        		**oc_orig_required;	/* MUST */
    char        		**oc_orig_allowed;	/* MAY */
	char				**oc_origin;	/* X-ORIGIN extension */
	struct objclass		*oc_next;
};

struct matchingRuleList {
    Slapi_MatchingRuleEntry *mr_entry;
    struct matchingRuleList *mrl_next;
};
 
/* List of the plugin index numbers */

/* Backend & Global Plugins */
#define PLUGIN_LIST_DATABASE 0
#define PLUGIN_LIST_PREOPERATION 1
#define PLUGIN_LIST_POSTOPERATION 2
#define PLUGIN_LIST_BEPREOPERATION 3
#define PLUGIN_LIST_BEPOSTOPERATION 4
#define PLUGIN_LIST_INTERNAL_PREOPERATION 5
#define PLUGIN_LIST_INTERNAL_POSTOPERATION 6
#define PLUGIN_LIST_EXTENDED_OPERATION 7
#define PLUGIN_LIST_BACKEND_MAX 8

/* Global Plugins */
#define PLUGIN_LIST_ACL 9
#define PLUGIN_LIST_MATCHINGRULE 10
#define PLUGIN_LIST_SYNTAX 11
#define PLUGIN_LIST_ENTRY 12
#define PLUGIN_LIST_OBJECT 13
#define PLUGIN_LIST_PWD_STORAGE_SCHEME 14
#define PLUGIN_LIST_VATTR_SP 15	/* DBDB */
#define PLUGIN_LIST_REVER_PWD_STORAGE_SCHEME 16
#define PLUGIN_LIST_LDBM_ENTRY_FETCH_STORE 17
#define PLUGIN_LIST_INDEX 18
#define PLUGIN_LIST_GLOBAL_MAX 19

/* plugin configuration attributes */
#define ATTR_PLUGIN_PATH				"nsslapd-pluginPath"
#define ATTR_PLUGIN_INITFN				"nsslapd-pluginInitFunc"
#define ATTR_PLUGIN_TYPE				"nsslapd-pluginType"
#define ATTR_PLUGIN_PLUGINID			"nsslapd-pluginId"
#define ATTR_PLUGIN_VERSION				"nsslapd-pluginVersion"
#define ATTR_PLUGIN_VENDOR				"nsslapd-pluginVendor"
#define ATTR_PLUGIN_DESC				"nsslapd-pluginDescription"
#define ATTR_PLUGIN_ENABLED				"nsslapd-pluginEnabled"
#define ATTR_PLUGIN_ARG					"nsslapd-pluginArg"
#define ATTR_PLUGIN_BACKEND				"nsslapd-backend"
#define ATTR_PLUGIN_SCHEMA_CHECK		"nsslapd-schemaCheck"
#define ATTR_PLUGIN_LOG_ACCESS			"nsslapd-logAccess"
#define ATTR_PLUGIN_LOG_AUDIT			"nsslapd-logAudit"
#define ATTR_PLUGIN_TARGET_SUBTREE		"nsslapd-targetSubtree"
#define ATTR_PLUGIN_BIND_SUBTREE		"nsslapd-bindSubtree"
#define ATTR_PLUGIN_INVOKE_FOR_REPLOP	"nsslapd-invokeForReplOp"
#define ATTR_PLUGIN_LOAD_NOW            "nsslapd-pluginLoadNow"
#define ATTR_PLUGIN_LOAD_GLOBAL         "nsslapd-pluginLoadGlobal"

/* plugin action states */
enum
{
	PLGC_OFF,			/* internal operation action is on */
	PLGC_ON,			/* internal operation action is off */
	PLGC_UPTOPLUGIN		/* internal operation action is left up to plugin */
};

/* special data specifications */
enum
{
	PLGC_DATA_LOCAL,				/* plugin has access to all data hosted by this server */
	PLGC_DATA_REMOTE,				/* plugin has access to all requests for data not hosted by this server */
	PLGC_DATA_BIND_ANONYMOUS,		/* plugin bind function should be invoked for anonymous binds */
	PLGC_DATA_BIND_ROOT,			/* plugin bind function should be invoked for directory manager binds */
	PLGC_DATA_MAX	
};

/* DataList definition */
struct datalist
{
	void	 **elements;		/* array of elements */
	int		 element_count;		/* number of elements in the array */
	int		 alloc_count;		/* number of allocated nodes in the array */
}datalist;

/* data available to plugins */
typedef struct target_data
{
	DataList	subtrees;						/* regular DIT subtrees acessible to the plugin */
	PRBool		special_data [PLGC_DATA_MAX];	/* array of special data specification */
}PluginTargetData;

struct pluginconfig{
	PluginTargetData plgc_target_subtrees;	/* list of subtrees accessible by the plugin */
	PluginTargetData plgc_bind_subtrees;	/* the list of subtrees for which plugin in invoked during bind operation */
	PRBool		     plgc_schema_check;		/* inidcates whether schema check is performed during internal op */
	PRBool		     plgc_log_change;		/* indicates whether changes are logged during internal op */
	PRBool		     plgc_log_access;		/* indicates whether internal op is recorded in access log */
	PRBool		     plgc_log_audit;		/* indicates whether internal op is recorded in audit log */	
	PRBool		     plgc_invoke_for_replop;/* indicates that plugin should be invoked for internal operations */
};

struct slapdplugin {
	void				*plg_private;	/* data private to plugin */
	char				*plg_version;	/* version of this plugin */
    int                 plg_argc;       /* argc from config file */
	char				**plg_argv;		/* args from config file */
	char				*plg_libpath;	/* library path for dll/so */
    char				*plg_initfunc;  /* init symbol */
	IFP					plg_close;		/* close function */
	Slapi_PluginDesc	plg_desc;		/* vendor's info */
    char				*plg_name;		/* used for plugin rdn in cn=config */
	struct slapdplugin	*plg_next;		/* for plugin lists */
	int					plg_type;		/* discriminates union */
    char				*plg_dn;		/* config dn for this plugin */
	struct slapdplugin  *plg_group;		/* pointer to the group to which this plugin belongs */
	struct pluginconfig plg_conf;		/* plugin configuration parameters */
	IFP					plg_cleanup;	/* cleanup function */
	IFP					plg_start;		/* start function */
	IFP plg_poststart; /* poststart function */

/* NOTE: These LDIF2DB and DB2LDIF fn pointers are internal only for now.
   I don't believe you can get these functions from a plug-in and
   then call them without knowing what IFP or VFP0 are.  (These aren't
   declared in slapi-plugin.h.)  More importantly, it's a pretty ugly
   way to get to these functions. (Do we want people to get locked into
   this?)

   The correct way to do this would be to expose these functions as 
   front-end API functions. We can fix this for the next release.
   (No one has the time right now.)
 */
	union { /* backend database plugin structure */
		struct plg_un_database_backend {
			IFP	plg_un_db_bind;	  	  /* bind */
			IFP	plg_un_db_unbind;	  /* unbind */
			IFP	plg_un_db_search;	  /* search */
			IFP	plg_un_db_next_search_entry;	/* iterate */
	        IFP plg_un_db_next_search_entry_ext;
	        IFP plg_un_db_entry_release;
			IFP	plg_un_db_compare;	  /* compare */
			IFP	plg_un_db_modify;	  /* modify */
			IFP	plg_un_db_modrdn;	  /* modrdn */
			IFP	plg_un_db_add;		  /* add */
			IFP	plg_un_db_delete;	  /* delete */
			IFP	plg_un_db_abandon;	  /* abandon */
			IFP	plg_un_db_config;	  /* config */
			IFP	plg_un_db_flush;	  /* close */
			IFP	plg_un_db_seq;	  	  /* sequence */
			IFP	plg_un_db_entry;	  /* entry send */
			IFP	plg_un_db_referral;   /* referral send */
			IFP	plg_un_db_result;	  /* result send */
			IFP	plg_un_db_ldif2db;	  /* ldif 2 database */
			IFP	plg_un_db_db2ldif;	  /* database 2 ldif */
			IFP	plg_un_db_db2index;	  /* database 2 index */
			IFP	plg_un_db_archive2db; /* ldif 2 database */
			IFP	plg_un_db_db2archive; /* database 2 ldif */
			IFP	plg_un_db_upgradedb;  /* convert old idl to new */
			IFP	plg_un_db_begin;	  /* dbase txn begin */
			IFP	plg_un_db_commit;	  /* dbase txn commit */
			IFP	plg_un_db_abort;	  /* dbase txn abort */
			IFP	plg_un_db_dbsize;	  /* database size */
			IFP	plg_un_db_dbtest;	  /* database size */
			IFP	plg_un_db_rmdb;		  /* database remove */
			IFP	plg_un_db_register_dn_callback; /* Register a function to call when a operation is applied to a given DN */
			IFP	plg_un_db_register_oc_callback; /* Register a function to call when a operation is applied to a given ObjectClass */
			IFP	plg_un_db_init_instance;  /* initializes new db instance */
			IFP	plg_un_db_wire_import;    /* fast replica update */
			IFP	plg_un_db_verify;	      /* verify db files */
			IFP	plg_un_db_add_schema;     /* add schema */
		} plg_un_db;
#define plg_bind		plg_un.plg_un_db.plg_un_db_bind
#define plg_unbind		plg_un.plg_un_db.plg_un_db_unbind
#define plg_search		plg_un.plg_un_db.plg_un_db_search
#define plg_next_search_entry	plg_un.plg_un_db.plg_un_db_next_search_entry
#define plg_next_search_entry_ext plg_un.plg_un_db.plg_un_db_next_search_entry_ext
#define plg_entry_release       plg_un.plg_un_db.plg_un_db_entry_release
#define plg_compare		plg_un.plg_un_db.plg_un_db_compare
#define plg_modify		plg_un.plg_un_db.plg_un_db_modify
#define plg_modrdn		plg_un.plg_un_db.plg_un_db_modrdn
#define plg_add			plg_un.plg_un_db.plg_un_db_add
#define plg_delete		plg_un.plg_un_db.plg_un_db_delete
#define plg_abandon		plg_un.plg_un_db.plg_un_db_abandon
#define plg_config		plg_un.plg_un_db.plg_un_db_config
#define plg_flush		plg_un.plg_un_db.plg_un_db_flush
#define plg_seq			plg_un.plg_un_db.plg_un_db_seq
#define plg_entry		plg_un.plg_un_db.plg_un_db_entry
#define plg_referral		plg_un.plg_un_db.plg_un_db_referral
#define plg_result		plg_un.plg_un_db.plg_un_db_result
#define plg_ldif2db		plg_un.plg_un_db.plg_un_db_ldif2db
#define plg_db2ldif		plg_un.plg_un_db.plg_un_db_db2ldif
#define plg_db2index		plg_un.plg_un_db.plg_un_db_db2index
#define plg_archive2db		plg_un.plg_un_db.plg_un_db_archive2db
#define plg_db2archive		plg_un.plg_un_db.plg_un_db_db2archive
#define plg_upgradedb		plg_un.plg_un_db.plg_un_db_upgradedb
#define plg_dbverify		plg_un.plg_un_db.plg_un_db_verify
#define plg_dbsize		plg_un.plg_un_db.plg_un_db_dbsize
#define plg_dbtest		plg_un.plg_un_db.plg_un_db_dbtest
#define plg_rmdb		plg_un.plg_un_db.plg_un_db_rmdb
#define plg_init_instance       plg_un.plg_un_db.plg_un_db_init_instance
#define plg_wire_import         plg_un.plg_un_db.plg_un_db_wire_import
#define plg_add_schema          plg_un.plg_un_db.plg_un_db_add_schema

		/* extended operation plugin structure */
		struct plg_un_protocol_extension {
			char	**plg_un_pe_exoids;	  /* exop oids */
			char	**plg_un_pe_exnames;  /* exop names (may be NULL) */
			IFP	plg_un_pe_exhandler;	  /* handler */
		} plg_un_pe;
#define plg_exoids		plg_un.plg_un_pe.plg_un_pe_exoids
#define plg_exnames		plg_un.plg_un_pe.plg_un_pe_exnames
#define plg_exhandler		plg_un.plg_un_pe.plg_un_pe_exhandler


		/* pre-operation plugin structure */
		struct plg_un_pre_operation {
			IFP	plg_un_pre_bind;  	  /* bind */
			IFP	plg_un_pre_unbind;	  /* unbind */
			IFP	plg_un_pre_search;	  /* search */
			IFP	plg_un_pre_compare;	  /* compare */
			IFP	plg_un_pre_modify;	  /* modify */
			IFP	plg_un_pre_modrdn;	  /* modrdn */
			IFP	plg_un_pre_add;		  /* add */
			IFP	plg_un_pre_delete;	  /* delete */
			IFP	plg_un_pre_abandon;	  /* abandon */
			IFP	plg_un_pre_entry;	  /* entry send */
			IFP	plg_un_pre_referral;	  /* referral send */
			IFP	plg_un_pre_result;	  /* result send */
		} plg_un_pre;
#define plg_prebind	plg_un.plg_un_pre.plg_un_pre_bind
#define plg_preunbind	plg_un.plg_un_pre.plg_un_pre_unbind
#define plg_presearch	plg_un.plg_un_pre.plg_un_pre_search
#define plg_precompare	plg_un.plg_un_pre.plg_un_pre_compare
#define plg_premodify	plg_un.plg_un_pre.plg_un_pre_modify
#define plg_premodrdn	plg_un.plg_un_pre.plg_un_pre_modrdn
#define plg_preadd	plg_un.plg_un_pre.plg_un_pre_add
#define plg_predelete	plg_un.plg_un_pre.plg_un_pre_delete
#define plg_preabandon	plg_un.plg_un_pre.plg_un_pre_abandon
#define plg_preentry	plg_un.plg_un_pre.plg_un_pre_entry
#define plg_prereferral	plg_un.plg_un_pre.plg_un_pre_referral
#define plg_preresult	plg_un.plg_un_pre.plg_un_pre_result

		/* post-operation plugin structure */
		struct plg_un_post_operation {
			IFP	plg_un_post_bind;  	  /* bind */
			IFP	plg_un_post_unbind;	  /* unbind */
			IFP	plg_un_post_search;	  /* search */
			IFP	plg_un_post_searchfail;	  /* failed search */
			IFP	plg_un_post_compare;	  /* compare */
			IFP	plg_un_post_modify;	  /* modify */
			IFP	plg_un_post_modrdn;	  /* modrdn */
			IFP	plg_un_post_add;	  /* add */
			IFP	plg_un_post_delete;	  /* delete */
			IFP	plg_un_post_abandon;	  /* abandon */
			IFP	plg_un_post_entry;	  /* entry send */
			IFP	plg_un_post_referral;	  /* referral send */
			IFP	plg_un_post_result;	  /* result send */
		} plg_un_post;
#define plg_postbind		plg_un.plg_un_post.plg_un_post_bind
#define plg_postunbind		plg_un.plg_un_post.plg_un_post_unbind
#define plg_postsearch		plg_un.plg_un_post.plg_un_post_search
#define plg_postsearchfail	plg_un.plg_un_post.plg_un_post_searchfail
#define plg_postcompare		plg_un.plg_un_post.plg_un_post_compare
#define plg_postmodify		plg_un.plg_un_post.plg_un_post_modify
#define plg_postmodrdn		plg_un.plg_un_post.plg_un_post_modrdn
#define plg_postadd		plg_un.plg_un_post.plg_un_post_add
#define plg_postdelete		plg_un.plg_un_post.plg_un_post_delete
#define plg_postabandon		plg_un.plg_un_post.plg_un_post_abandon
#define plg_postentry		plg_un.plg_un_post.plg_un_post_entry
#define plg_postreferral	plg_un.plg_un_post.plg_un_post_referral
#define plg_postresult		plg_un.plg_un_post.plg_un_post_result

        /* backend pre-operation plugin structure */
		struct plg_un_bepre_operation {
			IFP	plg_un_bepre_modify;	  /* modify */
			IFP	plg_un_bepre_modrdn;	  /* modrdn */
			IFP	plg_un_bepre_add;		  /* add */
			IFP	plg_un_bepre_delete;	  /* delete */
		} plg_un_bepre;
#define plg_bepremodify	plg_un.plg_un_bepre.plg_un_bepre_modify
#define plg_bepremodrdn	plg_un.plg_un_bepre.plg_un_bepre_modrdn
#define plg_bepreadd	plg_un.plg_un_bepre.plg_un_bepre_add
#define plg_bepredelete	plg_un.plg_un_bepre.plg_un_bepre_delete

		/* backend post-operation plugin structure */
		struct plg_un_bepost_operation {
			IFP	plg_un_bepost_modify;	  /* modify */
			IFP	plg_un_bepost_modrdn;	  /* modrdn */
			IFP	plg_un_bepost_add;	  /* add */
			IFP	plg_un_bepost_delete;	  /* delete */
		} plg_un_bepost;
#define plg_bepostmodify		plg_un.plg_un_bepost.plg_un_bepost_modify
#define plg_bepostmodrdn		plg_un.plg_un_bepost.plg_un_bepost_modrdn
#define plg_bepostadd			plg_un.plg_un_bepost.plg_un_bepost_add
#define plg_bepostdelete		plg_un.plg_un_bepost.plg_un_bepost_delete

        /* internal  pre-operation plugin structure */
		struct plg_un_internal_pre_operation {
			IFP	plg_un_internal_pre_modify;	  /* modify */
			IFP	plg_un_internal_pre_modrdn;	  /* modrdn */
			IFP	plg_un_internal_pre_add;		  /* add */
			IFP	plg_un_internal_pre_delete;	  /* delete */
		} plg_un_internal_pre;
#define plg_internal_pre_modify	plg_un.plg_un_internal_pre.plg_un_internal_pre_modify
#define plg_internal_pre_modrdn	plg_un.plg_un_internal_pre.plg_un_internal_pre_modrdn
#define plg_internal_pre_add	plg_un.plg_un_internal_pre.plg_un_internal_pre_add
#define plg_internal_pre_delete	plg_un.plg_un_internal_pre.plg_un_internal_pre_delete

		/* internal post-operation plugin structure */
		struct plg_un_internal_post_operation {
			IFP	plg_un_internal_post_modify;	  /* modify */
			IFP	plg_un_internal_post_modrdn;	  /* modrdn */
			IFP	plg_un_internal_post_add;	  /* add */
			IFP	plg_un_internal_post_delete;	  /* delete */
		} plg_un_internal_post;
#define plg_internal_post_modify		plg_un.plg_un_internal_post.plg_un_internal_post_modify
#define plg_internal_post_modrdn		plg_un.plg_un_internal_post.plg_un_internal_post_modrdn
#define plg_internal_post_add			plg_un.plg_un_internal_post.plg_un_internal_post_add
#define plg_internal_post_delete		plg_un.plg_un_internal_post.plg_un_internal_post_delete

		/* matching rule plugin structure */
		struct plg_un_matching_rule {
			IFP	plg_un_mr_filter_create; /* factory function */
			IFP	plg_un_mr_indexer_create; /* factory function */
		} plg_un_mr;
#define plg_mr_filter_create	plg_un.plg_un_mr.plg_un_mr_filter_create
#define plg_mr_indexer_create	plg_un.plg_un_mr.plg_un_mr_indexer_create

		/* syntax plugin structure */
		struct plg_un_syntax_struct {
			IFP	plg_un_syntax_filter_ava;
		    IFP plg_un_syntax_filter_ava_sv;
			IFP	plg_un_syntax_filter_sub;
			IFP	plg_un_syntax_filter_sub_sv;
			IFP	plg_un_syntax_values2keys;
		    IFP plg_un_syntax_values2keys_sv; 
			IFP	plg_un_syntax_assertion2keys_ava;
			IFP	plg_un_syntax_assertion2keys_sub;
			int	plg_un_syntax_flags;
/*
   from slapi-plugin.h
#define SLAPI_PLUGIN_SYNTAX_FLAG_ORKEYS		1
#define SLAPI_PLUGIN_SYNTAX_FLAG_ORDERING	2
*/
			char	**plg_un_syntax_names;
			char	*plg_un_syntax_oid;
			IFP	plg_un_syntax_compare;
		} plg_un_syntax;
#define plg_syntax_filter_ava		plg_un.plg_un_syntax.plg_un_syntax_filter_ava
#define plg_syntax_filter_sub		plg_un.plg_un_syntax.plg_un_syntax_filter_sub
#define plg_syntax_values2keys		plg_un.plg_un_syntax.plg_un_syntax_values2keys
#define plg_syntax_assertion2keys_ava	plg_un.plg_un_syntax.plg_un_syntax_assertion2keys_ava
#define plg_syntax_assertion2keys_sub	plg_un.plg_un_syntax.plg_un_syntax_assertion2keys_sub
#define plg_syntax_flags		plg_un.plg_un_syntax.plg_un_syntax_flags
#define plg_syntax_names		plg_un.plg_un_syntax.plg_un_syntax_names
#define plg_syntax_oid			plg_un.plg_un_syntax.plg_un_syntax_oid
#define plg_syntax_compare			plg_un.plg_un_syntax.plg_un_syntax_compare

		struct plg_un_acl_struct {
			IFP	plg_un_acl_init;
			IFP	plg_un_acl_syntax_check;
			IFP	plg_un_acl_access_allowed;
			IFP	plg_un_acl_mods_allowed;
			IFP	plg_un_acl_mods_update;
		} plg_un_acl;
#define plg_acl_init 			plg_un.plg_un_acl.plg_un_acl_init
#define plg_acl_syntax_check		plg_un.plg_un_acl.plg_un_acl_syntax_check
#define plg_acl_access_allowed 		plg_un.plg_un_acl.plg_un_acl_access_allowed
#define plg_acl_mods_allowed		plg_un.plg_un_acl.plg_un_acl_mods_allowed
#define plg_acl_mods_update		plg_un.plg_un_acl.plg_un_acl_mods_update

		/* password storage scheme (kexcoff) */
		struct plg_un_pwd_storage_scheme_struct {
			char *plg_un_pwd_storage_scheme_name;	/* SHA, SSHA...*/
			CFP plg_un_pwd_storage_scheme_enc;
			IFP plg_un_pwd_storage_scheme_dec;
			IFP plg_un_pwd_storage_scheme_cmp;
		} plg_un_pwd_storage_scheme;
#define plg_pwdstorageschemename plg_un.plg_un_pwd_storage_scheme.plg_un_pwd_storage_scheme_name
#define plg_pwdstorageschemeenc plg_un.plg_un_pwd_storage_scheme.plg_un_pwd_storage_scheme_enc
#define plg_pwdstorageschemedec plg_un.plg_un_pwd_storage_scheme.plg_un_pwd_storage_scheme_dec
#define plg_pwdstorageschemecmp plg_un.plg_un_pwd_storage_scheme.plg_un_pwd_storage_scheme_cmp

		/* entry fetch/store */
		struct plg_un_entry_fetch_store_struct {
			IFP plg_un_entry_fetch_func;
			IFP plg_un_entry_store_func;
		} plg_un_entry_fetch_store;
#define plg_entryfetchfunc plg_un.plg_un_entry_fetch_store.plg_un_entry_fetch_func
#define plg_entrystorefunc plg_un.plg_un_entry_fetch_store.plg_un_entry_store_func
	} plg_un;
};

/*
 * represents a "database"
 */

typedef struct backend {
	Slapi_DN **be_suffix;    /* the DN suffixes of data in this backend */
    PRLock *be_suffixlock;
    int be_suffixcount;
    char *be_basedn;     /* The base dn for the config & monitor dns */
	char *be_configdn;   /* The config dn for this backend          */
	char *be_monitordn;  /* The monitor dn for this backend          */
	int	be_readonly;     /* 1 => db is in "read only" mode	   */
	int	be_sizelimit;    /* size limit for this backend   	   */
	int	be_timelimit;    /* time limit for this backend       	   */
	int	be_maxnestlevel; /* Max nest level for acl group evaluation */
	int	be_noacl;        /* turn off front end acl for this be      */
	int	be_lastmod;      /* keep track of lastmodified{by,time}	   */
	char *be_type;       /* type of database			   */
	char *be_backendconfig; /* backend config filename */
	char **be_include;   /* include files within this db definition */
	int be_private;      /* Internal backends use this to hide from the user */
	int be_logchanges;   /* changes to this backend should be logged in the changelog */
    int (*be_writeconfig)(Slapi_PBlock *pb); /* function to call to make this
												backend write its conf file */
	/*
	 * backend database api function ptrs and args (to do operations)
	 */
	struct slapdplugin	*be_database;	/* single plugin */
#define be_bind			be_database->plg_bind
#define be_unbind		be_database->plg_unbind
#define be_search		be_database->plg_search
#define	be_next_search_entry be_database->plg_next_search_entry
#define be_next_search_entry_ext be_database->plg_next_search_entry_ext
#define be_entry_release be_database->plg_entry_release
#define be_compare		be_database->plg_compare
#define be_modify		be_database->plg_modify
#define be_modrdn		be_database->plg_modrdn
#define be_add			be_database->plg_add
#define be_delete		be_database->plg_delete
#define be_abandon		be_database->plg_abandon
#define be_config		be_database->plg_config
#define be_close		be_database->plg_close
#define be_flush		be_database->plg_flush
#define be_start		be_database->plg_start
#define be_poststart		be_database->plg_poststart
#define be_seq			be_database->plg_seq
#define be_ldif2db		be_database->plg_ldif2db
#define be_upgradedb		be_database->plg_upgradedb
#define be_db2ldif		be_database->plg_db2ldif
#define be_db2index		be_database->plg_db2index
#define be_archive2db	be_database->plg_archive2db
#define be_db2archive	be_database->plg_db2archive
#define be_dbsize		be_database->plg_dbsize
#define be_dbtest		be_database->plg_dbtest
#define be_rmdb			be_database->plg_rmdb
#define be_result		be_database->plg_result
#define be_init_instance be_database->plg_init_instance
#define be_cleanup		be_database->plg_cleanup
#define be_wire_import          be_database->plg_wire_import

	void *be_instance_info;		/* If the database plugin pointed to by
								 * be_database supports more than one instance,
								 * it can use this to keep track of the 
								 * multiple instances. */

	char *be_name;				/* The mapping tree and command line utils 
								 * refer to backends by name. */
	int be_mapped;				/* True if the be is represented by a node
								 * in the mapping tree. */

	/*struct slapdplugin	*be_plugin_list[PLUGIN_LIST_BACKEND_MAX]; list of plugins */
	
    int    be_delete_on_exit;	/* marks db for deletion - used to remove changelog*/
    int    be_state;			/* indicates current database state */ 
	PRLock *be_state_lock;		/* lock under which to modify the state */

    int     be_flags;		/* misc properties. See BE_FLAG_xxx defined in slapi-private.h */
	PRRWLock    *be_lock;	
	PRRWLock    *vlvSearchList_lock;
	void        *vlvSearchList;
} backend;

enum
{
	BE_STATE_STOPPED = 1,	/* backend is initialized but not started */
	BE_STATE_STARTED,		/* backend is started */
	BE_STATE_CLEANED,		/* backend was cleaned up */
	BE_STATE_DELETED		/* backend is removed */
};

struct conn;
struct op;

typedef void (*result_handler)( struct conn *, struct op *, int, char *,
	char *, int, struct berval ** );
typedef int (*search_entry_handler)( Slapi_Backend *, struct conn *, struct op *,
	struct slapi_entry * );
typedef int (*search_referral_handler)( Slapi_Backend *, struct conn *, struct op *,
	struct berval ** );
typedef CSN * (*csngen_handler)( Slapi_PBlock *pb, const CSN *basecsn );
typedef int (*replica_attr_handler)( Slapi_PBlock *pb, const char *type, void **value );

/*
 * LDAP Operation results.
 */
typedef struct slapi_operation_results
{
	unsigned long operation_type;

	int opreturn;

	LDAPControl	**result_controls;/* ctrls to be returned w/result  */

	int result_code;
	char*  result_text;
	char*  result_matched;

	union
	{
		struct bind_results
		{
			struct berval *bind_ret_saslcreds; /* v3 serverSaslCreds */
		} r_bind;

		struct search_results
		{
			/*
			 * Search results set - opaque cookie passed between backend
			 * and frontend to iterate over search results.
			 */
			void *search_result_set;
			/* Next entry returned from iterating */
			Slapi_Entry *search_result_entry;
		    /* opaque pointer owned by the backend.  Used in searches with 
			 * lookahead */
		    void *opaque_backend_ptr;
			/* number of entries sent in response to this search request */
			int nentries;
			/* Any referrals encountered during the search */
			struct berval **search_referrals;
		} r_search;

		struct extended_results
		{
			char *exop_ret_oid;
			struct berval *exop_ret_value;
		} r_extended;
	} r;
} slapi_operation_results;

/*
 * represents an operation pending from an ldap client
 */
typedef struct op {
	BerElement	*o_ber;		/* ber of the request		  */
	ber_int_t	o_msgid;	/* msgid of the request		  */
	ber_tag_t	o_tag;		/* tag of the request		  */
	time_t		o_time;		/* time op was initiated	  */
	PRIntervalTime	o_interval;	/* precise time op was initiated  */
	int		o_isroot;	/* requestor is manager		  */
	Slapi_DN	o_sdn;		/* dn bound when op was initiated */
	char		*o_authtype;	/* auth method used to bind dn	  */
	int		o_opid;		/* id of this operation		  */
	int		o_connid;	/* id of conn initiating this op; for logging only */
	void		*o_handler_data;
	result_handler		o_result_handler;
	search_entry_handler	o_search_entry_handler;
	search_referral_handler	o_search_referral_handler;
	csngen_handler		o_csngen_handler;
	replica_attr_handler	o_replica_attr_handler;
	struct op	*o_next;	/* next operation pending	  */
	int		o_status;		/* status (see SLAPI_OP_STATUS_... below */
	char		**o_searchattrs;/* original attr names requested  */ /* JCM - Search Param */
	unsigned long	o_flags;	/* flags for this operation	  */
	void *o_extension; /* plugins are able to extend the Operation object */
	Slapi_DN *o_target_spec; /* used to decide which plugins should be called for the operation */
	unsigned long o_abandoned_op; /* operation abandoned by this operation - used to decide which plugins to invoke */
	struct slapi_operation_parameters o_params;
	struct slapi_operation_results o_results;
} Operation;

/*
 * Operation status (o_status) values.
 * The normal progression is from PROCESSING to RESULT_SENT, with
 *   WILL_COMPLETE as an optional intermediate state.
 * For operations that are abandoned, the progression is from PROCESSING
 *   to ABANDONED.
 */
#define SLAPI_OP_STATUS_PROCESSING		0	/* the normal state */
#define SLAPI_OP_STATUS_ABANDONED		1	/* op. has been abandoned */
#define SLAPI_OP_STATUS_WILL_COMPLETE	2	/* no more abandon checks
												will be done */
#define SLAPI_OP_STATUS_RESULT_SENT		3	/* result has been sent to the
												client (or we tried to do
												so and failed) */

/*
 * represents a connection from an ldap client
 */

struct Conn_Private;
typedef struct Conn_private Conn_private;
struct _sasl_io_private;  
typedef struct _sasl_io_private sasl_io_private;

typedef struct conn {
	Sockbuf		*c_sb;		/* ber connection stuff		  */
	int		c_sd;		/* the actual socket descriptor	  */
	int		c_ldapversion;	/* version of LDAP protocol       */
	char		*c_dn;		/* current DN bound to this conn  */
	int		c_isroot;	/* c_dn was rootDN at time of bind? */
	int		c_isreplication_session;	/* this connection is a replication session */
	char		*c_authtype;	/* auth method used to bind c_dn  */
	char		*c_external_dn;	/* client DN of this SSL session  */
	char		*c_external_authtype; /* used for c_external_dn   */
        PRNetAddr	*cin_addr;	/* address of client on this conn */
	PRNetAddr	*cin_destaddr;	/* address client connected to    */
	struct berval	**c_domain;	/* DNS names of client            */
	Operation		*c_ops;		/* list of pending operations	  */
	int				c_gettingber;	/* in the middle of ber_get_next  */
	BerElement		*c_currentber;	/* ber we're getting              */
	time_t			c_starttime;	/* when the connection was opened */
	int				c_connid;	/* id of this connection for stats*/
	int				c_opsinitiated;	/* # ops initiated/next op id	  */
	PRInt32			c_opscompleted;	/* # ops completed		  */
	PRInt32			c_threadnumber; /* # threads used in this conn    */
	int				c_refcnt;	/* # ops refering to this conn    */
	PRLock			*c_mutex;	/* protect each conn structure    */
	PRLock			*c_pdumutex;	/* only write one pdu at a time   */
	time_t			c_idlesince;	/* last time of activity on conn  */
	Conn_private	*c_private;	/* data which is not shared outside*/
								/* connection.c 		  */
	int				c_flags;	/* Misc flags used only for SSL   */
								/* status currently               */
	int				c_needpw;	/* need new password 		  */
	CERTCertificate *c_client_cert;	/* Client's Cert		  */
	PRFileDesc	*	c_prfd;	/* NSPR 2.1 FileDesc		  */
	int             c_ci;       /* An index into the Connection array. For printing. */
	int             c_fdi;      /* An index into the FD array. The FD this connection is using. */
    struct conn *   c_next;         /* Pointer to the next and previous */
    struct conn *   c_prev;         /* active connections in the table*/
        Slapi_Backend *c_bi_backend;    /* which backend is doing the import */
	void *c_extension; /* plugins are able to extend the Connection object */
    void *c_sasl_conn;   /* sasl library connection sasl_conn_t */
    sasl_io_private *c_sasl_io_private; /* Private data for SASL I/O Layer */
    int				c_enable_sasl_io; /* Flag to tell us to enable SASL I/O on the next read */
    int				c_sasl_io; /* Flag to tell us to enable SASL I/O on the next read */
    int				c_sasl_ssf; /* flag to tell us the SASL SSF */
    int				c_unix_local; /* flag true for LDAPI */
    int				c_local_valid; /* flag true if the uid/gid are valid */
    uid_t			c_local_uid;  /* uid of connecting process */
    gid_t			c_local_gid;  /* gid of connecting process */
} Connection;
#define CONN_FLAG_SSL	1	/* Is this connection an SSL connection or not ? 
							 * Used to direct I/O code when SSL is handled differently 
							 */
#define CONN_FLAG_CLOSING 2    /* If this flag is set, then the connection has
				* been marked for closing by a worker thread 
				* and the listener thread should close it. */
#define CONN_FLAG_IMPORT 4      /* This connection has begun a bulk import
                                 * (aka "fast replica init" aka "wire import"),
                                 * so it can only accept adds & ext-ops.
                                 */


#define CONN_FLAG_SASL_CONTINUE 8     /* We're in a multi-stage sasl bind */

#define CONN_FLAG_START_TLS 16   /* Flag set when an SSL connection is so after an 
				  * Start TLS request operation. 
				  */

#define CONN_FLAG_SASL_COMPLETE 32  /* Flag set when a sasl bind has been 
                                     * successfully completed.
                                     */


#define START_TLS_OID    "1.3.6.1.4.1.1466.20037"


#ifndef _WIN32
#define SLAPD_POLL_FLAGS	(POLLIN)
#else
#define SLAPD_POLL_FLAGS	(PR_POLL_READ)
#endif

/******************************************************************************
 *  * Online tasks interface (to support import, export, etc)
 *   * After some cleanup, we could consider making these public.
 *    */
struct slapi_task {
    struct slapi_task *next;
    char *task_dn;
    int task_exitcode;          /* for the end user */
    int task_state;             /* current state of task */
    int task_progress;          /* number between 0 and task_work */
    int task_work;              /* "units" of work to be done */
    int task_flags;             /* (see above) */
    char *task_status;          /* transient status info */
    char *task_log;             /* appended warnings, etc */
    void *task_private;         /* allow opaque data to be stashed in the task */
    TaskCallbackFn cancel;      /* task has been cancelled by user */
    TaskCallbackFn destructor;  /* task entry is being destroyed */
    int task_refcount;
} slapi_task;
/* End of interface to support online tasks **********************************/

typedef struct slapi_pblock {
	/* common */
	Slapi_Backend		*pb_backend;
	Connection	*pb_conn;
	Operation	*pb_op;
	struct slapdplugin	*pb_plugin;	/* plugin being called */
	int		pb_opreturn;
	void*		pb_object;	/* points to data private to plugin */
	IFP		pb_destroy_fn;
	int		pb_requestor_isroot;
	/* config file */
	char		*pb_config_fname;
	int		pb_config_lineno;
	int		pb_config_argc;
	char		**pb_config_argv;

	/* [pre|post]add arguments */
	struct slapi_entry	*pb_target_entry; /* JCM - Duplicated */
	struct slapi_entry	*pb_existing_dn_entry;
	struct slapi_entry	*pb_existing_uniqueid_entry;
	struct slapi_entry	*pb_parent_entry;
	struct slapi_entry	*pb_newparent_entry;

	/* state of entry before and after add/delete/modify/moddn/modrdn */
	struct slapi_entry	*pb_pre_op_entry;
	struct slapi_entry	*pb_post_op_entry;
	/* seq access arguments */
	int             pb_seq_type;
	char            *pb_seq_attrname;
	char            *pb_seq_val;
	/* ldif2db arguments */
	char		*pb_ldif_file;
	int		pb_removedupvals;
	char		**pb_db2index_attrs;
	int		pb_ldif2db_noattrindexes;
	/* db2ldif arguments */
	int		pb_ldif_printkey;
	/* ldif2db/db2ldif/db2bak/bak2db args */
	char *pb_instance_name;
	Slapi_Task      *pb_task;
	int		pb_task_flags;
	/* matching rule arguments */
	mrFilterMatchFn	pb_mr_filter_match_fn;
	IFP		pb_mr_filter_index_fn;
	IFP		pb_mr_filter_reset_fn;
	IFP		pb_mr_index_fn;
	char*		pb_mr_oid;
	char*		pb_mr_type;
	struct berval*	pb_mr_value;
	struct berval**	pb_mr_values;
	struct berval**	pb_mr_keys;
	unsigned int	pb_mr_filter_reusable;
	int		pb_mr_query_operator;
	unsigned int	pb_mr_usage;

	/* arguments for password storage scheme (kexcoff) */
	char *pb_pwd_storage_scheme_user_passwd;
	char *pb_pwd_storage_scheme_db_passwd;

	/* controls we know about */
	int		pb_managedsait;

    /* additional fields for plugin_internal_ldap_ops */
	/* result code of internal ldap_operation */
    int		pb_internal_op_result;
	/* pointer to array of results returned on search */
	Slapi_Entry	**pb_plugin_internal_search_op_entries;
	char		**pb_plugin_internal_search_op_referrals;
	void		*pb_plugin_identity; /* identifies plugin for internal operation */
	void		*pb_parent_txn;	/* parent transaction ID */
	void		*pb_txn;		/* transaction ID */

	/* Size of the database on disk, in kilobytes */
	unsigned int	pb_dbsize;

	/* THINGS BELOW THIS LINE EXIST ONLY IN SLAPI v2 (slapd 4.0+) */

	/* ldif2db: array of files to import all at once */
	char **pb_ldif_files;

	char		**pb_ldif_include;
	char		**pb_ldif_exclude;
	int		pb_ldif_dump_replica;
	int		pb_ldif_dump_uniqueid;		/* dump uniqueid during db2ldif */
	int		pb_ldif_generate_uniqueid;	/* generate uniqueid during db2ldif */
	char*     pb_ldif_namespaceid;		/* used for name based uniqueid generation */ 
	int     pb_ldif_encrypt;		/* used to enable encrypt/decrypt on import and export */ 
	/*
	 * notes to log with RESULT line in the access log
	 * these are actually stored as a bitmap; see slapi-plugin.h for
	 *	defined notes.
	 */
	unsigned int	pb_operation_notes;
	/*
	 * slapd command line arguments
	 */
	int pb_slapd_argc;
	char** pb_slapd_argv;
	char *pb_slapd_configdir; /* the config directory passed to slapd on the command line */
	LDAPControl	**pb_ctrls_arg; /* allows to pass controls as arguments before
								   operation object is created  */
	int pb_dse_dont_add_write; /* if true, the dse is not written when an entry is added */
	int pb_dse_add_merge; /* if true, if a duplicate entry is found when adding, the 
							 new values are merged into the old entry */
	int pb_dse_dont_check_dups; /* if false, use the "enhanced" version of str2entry to catch
								   more errors when adding dse entries; this can only be done
								   after the schema and syntax and matching rule plugins are
								   running */
	int pb_dse_is_primary_file;	/* for read callbacks: non-zero for primary file */
	int pb_schema_flags; 		/* schema flags */
								/* . check/load info (schema reload task) */
								/* . refresh user defined schema */

	/* NEW in 5.0 for getting back the backend result in frontend */
	int pb_result_code;			/* operation result code */
	char * pb_result_text;		/* result text when available */
	char * pb_result_matched;	/* macthed dn when NO SUCH OBJECT  error */
	int pb_nentries;			/* number of entries to be returned */
	struct berval **urls;		/* urls of referrals to be returned */

    /*
     * wire import (fast replica init) arguments
     */
    struct slapi_entry *pb_import_entry;
    int pb_import_state;

    int pb_destroy_content;     /* flag to indicate that pblock content should be
                                   destroyed when pblock is destroyed */
	int pb_dse_reapply_mods; /* if true, dse_modify will reapply mods after modify callback */
	char * pb_urp_naming_collision_dn;	/* replication naming conflict removal */
	char * pb_urp_tombstone_uniqueid;	/* replication change tombstone */
	int		pb_server_running; /* indicate that server is running */
	int		pb_backend_count;  /* instance count involved in the op */

	/* For password policy control */
	int		pb_pwpolicy_ctrl;
	void	*pb_vattr_context;      /* hold the vattr_context for roles/cos */

	int		*pb_substrlens; /* user specified minimum substr search key lengths:
							 * nsSubStrBegin, nsSubStrMiddle, nsSubStrEnd
							 */
} slapi_pblock;

/* index if substrlens */
#define INDEX_SUBSTRBEGIN	0
#define INDEX_SUBSTRMIDDLE	1
#define INDEX_SUBSTREND		2
#define INDEX_SUBSTRLEN		3	/* size of the substrlens */

/* The referral element */
typedef struct ref {
     char          *ref_dn;       /* The DN of the entry that contains the referral */
     struct berval *ref_referral; /* The referral. It looks like: ldap://host:port */
     int            ref_reads;    /* 1 if refer searches, 0 else */
     int            ref_writes;   /* 1 if refer modifications, 0 else */
} Ref;

/* The head of the referral array. */
typedef struct ref_array {
    rwl	     *ra_rwlock;    /* Read-write lock struct to protect this thing */
    int       ra_size;      /* The size of this puppy (NOT the number of entries)*/
    int       ra_nextindex; /* The next free index */
    int       ra_readcount; /* The number of copyingfroms in the list */
    Ref     **ra_refs;      /* The array of referrals*/
} Ref_Array;

#define GR_LOCK_READ()    grefs->ra_rwlock->rwl_acquire_read_lock( grefs->ra_rwlock)
#define GR_UNLOCK_READ()  grefs->ra_rwlock->rwl_relinquish_read_lock( grefs->ra_rwlock )
#define GR_LOCK_WRITE()   grefs->ra_rwlock->rwl_acquire_write_lock( grefs->ra_rwlock )
#define GR_UNLOCK_WRITE() grefs->ra_rwlock->rwl_relinquish_write_lock( grefs->ra_rwlock )

/*
 * This structure is used to pass a pair of port numbers to the daemon
 * function. The daemon is the root of a forked thread.
 */

typedef struct daemon_ports_s {
	int			n_port;
	int			s_port;
	PRNetAddr	**n_listenaddr;
	PRNetAddr	**s_listenaddr;
#if defined( XP_WIN32 )
	int		n_socket;
	int		s_socket_native;
#else
	PRFileDesc	**n_socket;
#if defined(ENABLE_LDAPI)
	/* ldapi */
	PRNetAddr       **i_listenaddr;
	int             i_port; /* used as a flag only */
	PRFileDesc      **i_socket;
#endif
#endif
	PRFileDesc	**s_socket;
} daemon_ports_t;


/* Definition for plugin syntax compare routine */
typedef int (*value_compare_fn_type)(const struct berval *,const struct berval *);

#include "pw.h"

#include "proto-slap.h"
LDAPMod** entry2mods(Slapi_Entry *, LDAPMod **, int *, int);

/* SNMP Variables */
struct snmp_ops_tbl_t{
    PRUint32 *dsAnonymousBinds;
    PRUint32 *dsUnAuthBinds;
    PRUint32 *dsSimpleAuthBinds;
    PRUint32 *dsStrongAuthBinds;
    PRUint32 *dsBindSecurityErrors;
    PRUint32 *dsInOps;
    PRUint32 *dsReadOps;
    PRUint32 *dsCompareOps;
    PRUint32 *dsAddEntryOps;
    PRUint32 *dsRemoveEntryOps;
    PRUint32 *dsModifyEntryOps;
    PRUint32 *dsModifyRDNOps;
    PRUint32 *dsListOps;
    PRUint32 *dsSearchOps;
    PRUint32 *dsOneLevelSearchOps;
    PRUint32 *dsWholeSubtreeSearchOps;
    PRUint32 *dsReferrals;
    PRUint32 *dsChainings;
    PRUint32 *dsSecurityErrors;
    PRUint32 *dsErrors;
    PRUint32 *dsConnections;	 /* Number of currently connected clients */
    PRUint32 *dsConnectionSeq; /* Monotonically increasing number bumped on each new conn est */
    PRUint32 *dsBytesRecv;	/* Count of bytes read from clients */
    PRUint32 *dsBytesSent;	/* Count of bytes sent to clients */
    PRUint32 *dsEntriesReturned;
    PRUint32 *dsReferralsReturned;
};

struct snmp_entries_tbl_t{
   /* entries table */
   PRUint32 *dsMasterEntries;
   PRUint32 *dsCopyEntries;
   PRUint32 *dsCacheEntries;
   PRUint32 *dsCacheHits;
   PRUint32 *dsSlaveHits;
};

struct snmp_int_tbl_t{

   /* interaction table */
   PRUint32 *dsIntIndex;
   char *dsName;
   time_t *dsTimeOfCreation;          
   time_t *dsTimeOfLastAttempt;      
   time_t *dsTimeOfLastSuccess;      
   PRUint32 *dsFailuresSinceLastSuccess;
   PRUint32 *dsFailures;
   PRUint32 *dsSuccesses;
   char *dsURL;
};

/* operation statistics */
struct snmp_vars_t{
    struct snmp_ops_tbl_t ops_tbl;
    struct snmp_entries_tbl_t entries_tbl;
    struct snmp_int_tbl_t int_tbl[NUM_SNMP_INT_TBL_ROWS];
};

#define ENTRY_POINT_PS_WAKEUP_ALL	102
#define ENTRY_POINT_PS_SERVICE		105
#define ENTRY_POINT_DISCONNECT_SERVER	107
#define ENTRY_POINT_SLAPD_SSL_CLIENT_INIT	108
#define ENTRY_POINT_SLAPD_SSL_INIT	109
#define ENTRY_POINT_SLAPD_SSL_INIT2	110

typedef void (*ps_wakeup_all_fn_ptr)( void );
typedef void (*ps_service_fn_ptr)(Slapi_Entry *, Slapi_Entry *, int, int );
typedef char *(*get_config_dn_fn_ptr)();
typedef void (*get_disconnect_server_fn_ptr)(Connection *conn, int opconnid, int opid, PRErrorCode reason, PRInt32 error );
typedef int (*slapd_SSL_client_init_fn_ptr)( void );
typedef int (*modify_config_dse_fn_ptr)( Slapi_PBlock *pb );
typedef int (*slapd_ssl_init_fn_ptr)( void );
typedef int (*slapd_ssl_init_fn_ptr2)( PRFileDesc **s, int StartTLS);

/*
 * A structure of entry points in the NT exe which need
 * to be available to DLLs.
 */
typedef struct _slapdEntryPoints {
    caddr_t	sep_ps_wakeup_all;
    caddr_t	sep_ps_service;
    caddr_t	sep_disconnect_server;
    caddr_t	sep_slapd_SSL_client_init;
    caddr_t	sep_slapd_ssl_init;
    caddr_t	sep_slapd_ssl_init2;
} slapdEntryPoints;

#if defined( XP_WIN32 )
#define DLL_IMPORT_DATA _declspec( dllimport )
#else
#define DLL_IMPORT_DATA
#endif

/* Log types */
#define SLAPD_ACCESS_LOG 0x1
#define SLAPD_ERROR_LOG  0x2
#define SLAPD_AUDIT_LOG  0x4

#define CONFIG_DATABASE_ATTRIBUTE       "nsslapd-database"
#define CONFIG_PLUGIN_ATTRIBUTE         "nsslapd-plugin"
#define CONFIG_SIZELIMIT_ATTRIBUTE      "nsslapd-sizelimit"
#define CONFIG_TIMELIMIT_ATTRIBUTE      "nsslapd-timelimit"
#define CONFIG_SUFFIX_ATTRIBUTE         "nsslapd-suffix"
#define CONFIG_READONLY_ATTRIBUTE       "nsslapd-readonly"
#define CONFIG_REFERRAL_ATTRIBUTE       "nsslapd-referral"
#define CONFIG_OBJECTCLASS_ATTRIBUTE    "nsslapd-objectclass"
#define CONFIG_ATTRIBUTE_ATTRIBUTE      "nsslapd-attribute"
#define CONFIG_SCHEMACHECK_ATTRIBUTE    "nsslapd-schemacheck"
#define CONFIG_DS4_COMPATIBLE_SCHEMA_ATTRIBUTE    "nsslapd-ds4-compatible-schema"
#define CONFIG_SCHEMA_IGNORE_TRAILING_SPACES    "nsslapd-schema-ignore-trailing-spaces"
#define CONFIG_SCHEMAREPLACE_ATTRIBUTE	"nsslapd-schemareplace"
#define CONFIG_LOGLEVEL_ATTRIBUTE       "nsslapd-errorlog-level"
#define CONFIG_ACCESSLOGLEVEL_ATTRIBUTE "nsslapd-accesslog-level"
#define CONFIG_ACCESSLOG_MODE_ATTRIBUTE	"nsslapd-accesslog-mode"
#define CONFIG_ERRORLOG_MODE_ATTRIBUTE	"nsslapd-errorlog-mode"
#define CONFIG_AUDITLOG_MODE_ATTRIBUTE	"nsslapd-auditlog-mode"
#define CONFIG_ACCESSLOG_MAXNUMOFLOGSPERDIR_ATTRIBUTE "nsslapd-accesslog-maxlogsperdir"
#define CONFIG_ERRORLOG_MAXNUMOFLOGSPERDIR_ATTRIBUTE  "nsslapd-errorlog-maxlogsperdir"
#define CONFIG_AUDITLOG_MAXNUMOFLOGSPERDIR_ATTRIBUTE  "nsslapd-auditlog-maxlogsperdir"
#define CONFIG_ACCESSLOG_MAXLOGSIZE_ATTRIBUTE "nsslapd-accesslog-maxlogsize"
#define CONFIG_ERRORLOG_MAXLOGSIZE_ATTRIBUTE "nsslapd-errorlog-maxlogsize"
#define CONFIG_AUDITLOG_MAXLOGSIZE_ATTRIBUTE "nsslapd-auditlog-maxlogsize"
#define CONFIG_ACCESSLOG_LOGROTATIONSYNCENABLED_ATTRIBUTE "nsslapd-accesslog-logrotationsync-enabled"
#define CONFIG_ERRORLOG_LOGROTATIONSYNCENABLED_ATTRIBUTE "nsslapd-errorlog-logrotationsync-enabled"
#define CONFIG_AUDITLOG_LOGROTATIONSYNCENABLED_ATTRIBUTE "nsslapd-auditlog-logrotationsync-enabled"
#define CONFIG_ACCESSLOG_LOGROTATIONSYNCHOUR_ATTRIBUTE "nsslapd-accesslog-logrotationsynchour"
#define CONFIG_ERRORLOG_LOGROTATIONSYNCHOUR_ATTRIBUTE "nsslapd-errorlog-logrotationsynchour"
#define CONFIG_AUDITLOG_LOGROTATIONSYNCHOUR_ATTRIBUTE "nsslapd-auditlog-logrotationsynchour"
#define CONFIG_ACCESSLOG_LOGROTATIONSYNCMIN_ATTRIBUTE "nsslapd-accesslog-logrotationsyncmin"
#define CONFIG_ERRORLOG_LOGROTATIONSYNCMIN_ATTRIBUTE "nsslapd-errorlog-logrotationsyncmin"
#define CONFIG_AUDITLOG_LOGROTATIONSYNCMIN_ATTRIBUTE "nsslapd-auditlog-logrotationsyncmin"
#define CONFIG_ACCESSLOG_LOGROTATIONTIME_ATTRIBUTE "nsslapd-accesslog-logrotationtime"
#define CONFIG_ERRORLOG_LOGROTATIONTIME_ATTRIBUTE "nsslapd-errorlog-logrotationtime"
#define CONFIG_AUDITLOG_LOGROTATIONTIME_ATTRIBUTE "nsslapd-auditlog-logrotationtime"
#define CONFIG_ACCESSLOG_LOGROTATIONTIMEUNIT_ATTRIBUTE "nsslapd-accesslog-logrotationtimeunit"
#define CONFIG_ERRORLOG_LOGROTATIONTIMEUNIT_ATTRIBUTE "nsslapd-errorlog-logrotationtimeunit"
#define CONFIG_AUDITLOG_LOGROTATIONTIMEUNIT_ATTRIBUTE "nsslapd-auditlog-logrotationtimeunit"
#define CONFIG_ACCESSLOG_MAXLOGDISKSPACE_ATTRIBUTE "nsslapd-accesslog-logmaxdiskspace"
#define CONFIG_ERRORLOG_MAXLOGDISKSPACE_ATTRIBUTE "nsslapd-errorlog-logmaxdiskspace"
#define CONFIG_AUDITLOG_MAXLOGDISKSPACE_ATTRIBUTE "nsslapd-auditlog-logmaxdiskspace"
#define CONFIG_ACCESSLOG_MINFREEDISKSPACE_ATTRIBUTE "nsslapd-accesslog-logminfreediskspace"
#define CONFIG_ERRORLOG_MINFREEDISKSPACE_ATTRIBUTE "nsslapd-errorlog-logminfreediskspace"
#define CONFIG_AUDITLOG_MINFREEDISKSPACE_ATTRIBUTE "nsslapd-auditlog-logminfreediskspace"
#define CONFIG_ACCESSLOG_LOGEXPIRATIONTIME_ATTRIBUTE "nsslapd-accesslog-logexpirationtime"
#define CONFIG_ERRORLOG_LOGEXPIRATIONTIME_ATTRIBUTE "nsslapd-errorlog-logexpirationtime"
#define CONFIG_AUDITLOG_LOGEXPIRATIONTIME_ATTRIBUTE "nsslapd-auditlog-logexpirationtime"
#define CONFIG_ACCESSLOG_LOGEXPIRATIONTIMEUNIT_ATTRIBUTE "nsslapd-accesslog-logexpirationtimeunit"
#define CONFIG_ERRORLOG_LOGEXPIRATIONTIMEUNIT_ATTRIBUTE "nsslapd-errorlog-logexpirationtimeunit"
#define CONFIG_AUDITLOG_LOGEXPIRATIONTIMEUNIT_ATTRIBUTE "nsslapd-auditlog-logexpirationtimeunit"
#define CONFIG_ACCESSLOG_LOGGING_ENABLED_ATTRIBUTE "nsslapd-accesslog-logging-enabled"
#define CONFIG_ERRORLOG_LOGGING_ENABLED_ATTRIBUTE "nsslapd-errorlog-logging-enabled"
#define CONFIG_AUDITLOG_LOGGING_ENABLED_ATTRIBUTE "nsslapd-auditlog-logging-enabled"
#define CONFIG_ROOTDN_ATTRIBUTE "nsslapd-rootdn"
#define CONFIG_ROOTPW_ATTRIBUTE "nsslapd-rootpw"
#define CONFIG_ROOTPWSTORAGESCHEME_ATTRIBUTE "nsslapd-rootpwstoragescheme"
#define CONFIG_AUDITFILE_ATTRIBUTE "nsslapd-auditlog"
#define CONFIG_LASTMOD_ATTRIBUTE   "nsslapd-lastmod"
#define CONFIG_INCLUDE_ATTRIBUTE   "nsslapd-include"
#define CONFIG_DYNAMICCONF_ATTRIBUTE "nsslapd-dynamicconf"
#define CONFIG_USEROC_ATTRIBUTE "nsslapd-useroc"
#define CONFIG_USERAT_ATTRIBUTE "nsslapd-userat"
#define CONFIG_SVRTAB_ATTRIBUTE "nsslapd-svrtab"
#ifndef _WIN32
#define CONFIG_LOCALUSER_ATTRIBUTE "nsslapd-localuser"
#endif /* !_WIN32 */
#define CONFIG_LOCALHOST_ATTRIBUTE "nsslapd-localhost"
#define CONFIG_PORT_ATTRIBUTE "nsslapd-port"
#define CONFIG_WORKINGDIR_ATTRIBUTE "nsslapd-workingdir"
#define CONFIG_LISTENHOST_ATTRIBUTE "nsslapd-listenhost"
#define CONFIG_LDAPI_FILENAME_ATTRIBUTE "nsslapd-ldapifilepath"
#define CONFIG_LDAPI_SWITCH_ATTRIBUTE "nsslapd-ldapilisten"
#define CONFIG_LDAPI_BIND_SWITCH_ATTRIBUTE "nsslapd-ldapiautobind"
#define CONFIG_LDAPI_ROOT_DN_ATTRIBUTE "nsslapd-ldapimaprootdn"
#define CONFIG_LDAPI_MAP_ENTRIES_ATTRIBUTE "nsslapd-ldapimaptoentries"
#define CONFIG_LDAPI_UIDNUMBER_TYPE_ATTRIBUTE "nsslapd-ldapiuidnumbertype"
#define CONFIG_LDAPI_GIDNUMBER_TYPE_ATTRIBUTE "nsslapd-ldapigidnumbertype"
#define CONFIG_LDAPI_SEARCH_BASE_DN_ATTRIBUTE "nsslapd-ldapientrysearchbase"
#define CONFIG_LDAPI_AUTO_DN_SUFFIX_ATTRIBUTE "nsslapd-ldapiautodnsuffix"
#define CONFIG_SECURITY_ATTRIBUTE "nsslapd-security"
#define CONFIG_SSL3CIPHERS_ATTRIBUTE "nsslapd-SSL3ciphers"
#define CONFIG_ACCESSLOG_ATTRIBUTE "nsslapd-accesslog"
#define CONFIG_ERRORLOG_ATTRIBUTE "nsslapd-errorlog"
#define CONFIG_SECUREPORT_ATTRIBUTE "nsslapd-securePort"
#define CONFIG_SECURELISTENHOST_ATTRIBUTE "nsslapd-securelistenhost"
#define CONFIG_THREADNUMBER_ATTRIBUTE "nsslapd-threadnumber"
#define CONFIG_MAXTHREADSPERCONN_ATTRIBUTE "nsslapd-maxthreadsperconn"
#if !defined(_WIN32) && !defined(AIX)
#define CONFIG_MAXDESCRIPTORS_ATTRIBUTE "nsslapd-maxdescriptors"
#endif /* !_WIN32 && ! AIX */
#define CONFIG_CONNTABLESIZE_ATTRIBUTE "nsslapd-conntablesize"
#define CONFIG_RESERVEDESCRIPTORS_ATTRIBUTE "nsslapd-reservedescriptors"
#define CONFIG_IDLETIMEOUT_ATTRIBUTE "nsslapd-idletimeout"
#define CONFIG_IOBLOCKTIMEOUT_ATTRIBUTE "nsslapd-ioblocktimeout"
#define CONFIG_ACCESSCONTROL_ATTRIBUTE "nsslapd-accesscontrol"
#define CONFIG_GROUPEVALNESTLEVEL_ATTRIBUTE "nsslapd-groupevalnestlevel"
#define CONFIG_NAGLE_ATTRIBUTE "nsslapd-nagle"
#define CONFIG_PWPOLICY_LOCAL_ATTRIBUTE "nsslapd-pwpolicy-local"
#define CONFIG_PW_CHANGE_ATTRIBUTE "passwordChange"
#define CONFIG_PW_MUSTCHANGE_ATTRIBUTE "passwordMustChange"
#define CONFIG_PW_SYNTAX_ATTRIBUTE "passwordCheckSyntax"
#define CONFIG_PW_MINLENGTH_ATTRIBUTE "passwordMinLength"
#define CONFIG_PW_MINDIGITS_ATTRIBUTE "passwordMinDigits"
#define CONFIG_PW_MINALPHAS_ATTRIBUTE "passwordMinAlphas"
#define CONFIG_PW_MINUPPERS_ATTRIBUTE "passwordMinUppers"
#define CONFIG_PW_MINLOWERS_ATTRIBUTE "passwordMinLowers"
#define CONFIG_PW_MINSPECIALS_ATTRIBUTE "passwordMinSpecials"
#define CONFIG_PW_MIN8BIT_ATTRIBUTE "passwordMin8Bit"
#define CONFIG_PW_MAXREPEATS_ATTRIBUTE "passwordMaxRepeats"
#define CONFIG_PW_MINCATEGORIES_ATTRIBUTE "passwordMinCategories"
#define CONFIG_PW_MINTOKENLENGTH_ATTRIBUTE "passwordMinTokenLength"
#define CONFIG_PW_EXP_ATTRIBUTE "passwordExp"
#define CONFIG_PW_MAXAGE_ATTRIBUTE "passwordMaxAge"
#define CONFIG_PW_MINAGE_ATTRIBUTE "passwordMinAge"
#define CONFIG_PW_WARNING_ATTRIBUTE "passwordWarning"
#define CONFIG_PW_HISTORY_ATTRIBUTE "passwordHistory"
#define CONFIG_PW_INHISTORY_ATTRIBUTE "passwordInHistory"
#define CONFIG_PW_LOCKOUT_ATTRIBUTE "passwordLockout"
#define CONFIG_PW_STORAGESCHEME_ATTRIBUTE "passwordStorageScheme"
#define CONFIG_PW_MAXFAILURE_ATTRIBUTE "passwordMaxFailure"
#define CONFIG_PW_UNLOCK_ATTRIBUTE "passwordUnlock"
#define CONFIG_PW_LOCKDURATION_ATTRIBUTE "passwordLockoutDuration"
#define CONFIG_PW_RESETFAILURECOUNT_ATTRIBUTE "passwordResetFailureCount"
#define CONFIG_PW_ISGLOBAL_ATTRIBUTE "passwordIsGlobalPolicy"
#define CONFIG_PW_GRACELIMIT_ATTRIBUTE "passwordGraceLimit"
#define CONFIG_ACCESSLOG_BUFFERING_ATTRIBUTE "nsslapd-accesslog-logbuffering"
#define CONFIG_CSNLOGGING_ATTRIBUTE "nsslapd-csnlogging"
#define CONFIG_RETURN_EXACT_CASE_ATTRIBUTE "nsslapd-return-exact-case"
#define CONFIG_RESULT_TWEAK_ATTRIBUTE "nsslapd-result-tweak"
#define CONFIG_REFERRAL_MODE_ATTRIBUTE		"nsslapd-referralmode"
#define CONFIG_ATTRIBUTE_NAME_EXCEPTION_ATTRIBUTE "nsslapd-attribute-name-exceptions"
#define CONFIG_MAXBERSIZE_ATTRIBUTE "nsslapd-maxbersize"
#define CONFIG_MAX_FILTER_NEST_LEVEL_ATTRIBUTE "nsslapd-max-filter-nest-level"
#define CONFIG_VERSIONSTRING_ATTRIBUTE "nsslapd-versionstring"
#define CONFIG_ENQUOTE_SUP_OC_ATTRIBUTE "nsslapd-enquote-sup-oc"
#define CONFIG_BASEDN_ATTRIBUTE "nsslapd-certmap-basedn"
#define CONFIG_ACCESSLOG_LIST_ATTRIBUTE "nsslapd-accesslog-list"
#define CONFIG_ERRORLOG_LIST_ATTRIBUTE "nsslapd-errorlog-list"
#define CONFIG_AUDITLOG_LIST_ATTRIBUTE "nsslapd-auditlog-list"
#define CONFIG_REWRITE_RFC1274_ATTRIBUTE "nsslapd-rewrite-rfc1274"

#define CONFIG_CONFIG_ATTRIBUTE "nsslapd-config"
#define CONFIG_INSTDIR_ATTRIBUTE "nsslapd-instancedir"
#define CONFIG_SCHEMADIR_ATTRIBUTE "nsslapd-schemadir"
#define CONFIG_LOCKDIR_ATTRIBUTE "nsslapd-lockdir"
#define CONFIG_TMPDIR_ATTRIBUTE "nsslapd-tmpdir"
#define CONFIG_CERTDIR_ATTRIBUTE "nsslapd-certdir"
#define CONFIG_LDIFDIR_ATTRIBUTE "nsslapd-ldifdir"
#define CONFIG_BAKDIR_ATTRIBUTE "nsslapd-bakdir"
#define CONFIG_SASLPATH_ATTRIBUTE "nsslapd-saslpath"
#define CONFIG_RUNDIR_ATTRIBUTE "nsslapd-rundir"
#define CONFIG_SSLCLIENTAUTH_ATTRIBUTE "nsslapd-SSLclientAuth"
#define CONFIG_SSL_CHECK_HOSTNAME_ATTRIBUTE "nsslapd-ssl-check-hostname"
#define CONFIG_HASH_FILTERS_ATTRIBUTE "nsslapd-hash-filters"
#define CONFIG_OUTBOUND_LDAP_IO_TIMEOUT_ATTRIBUTE "nsslapd-outbound-ldap-io-timeout"

#ifdef MEMPOOL_EXPERIMENTAL
#define CONFIG_MEMPOOL_SWITCH_ATTRIBUTE "nsslapd-mempool"
#define CONFIG_MEMPOOL_MAXFREELIST_ATTRIBUTE "nsslapd-mempool-maxfreelist"
#endif /* MEMPOOL_EXPERIMENTAL */

/* flag used to indicate that the change to the config parameter should be saved */
#define CONFIG_APPLY 1

#define CFG_LOCK_READ(cfg)   cfg->cfg_rwlock->rwl_acquire_read_lock( cfg->cfg_rwlock )
#define CFG_UNLOCK_READ(cfg) cfg->cfg_rwlock->rwl_relinquish_read_lock( cfg->cfg_rwlock )
#define CFG_LOCK_WRITE(cfg)   cfg->cfg_rwlock->rwl_acquire_write_lock( cfg->cfg_rwlock )
#define CFG_UNLOCK_WRITE(cfg) cfg->cfg_rwlock->rwl_relinquish_write_lock( cfg->cfg_rwlock )

#define REFER_MODE_OFF 0 
#define REFER_MODE_ON 1

#define MAX_ALLOWED_TIME_IN_SECS	2147483647

typedef struct passwordpolicyarray {
  int pw_change;        /* 1 - indicates that users are allowed to change the pwd */
  int pw_must_change;   /* 1 - indicates that users must change pwd upon reset */
  int pw_syntax;
  int pw_minlength;
  int pw_mindigits;
  int pw_minalphas;
  int pw_minuppers;
  int pw_minlowers;
  int pw_minspecials;
  int pw_min8bit;
  int pw_maxrepeats;
  int pw_mincategories;
  int pw_mintokenlength;
  int pw_exp;
  long pw_maxage;
  long pw_minage;
  long pw_warning;
  int pw_history;
  int pw_inhistory;
  int pw_lockout;
  int pw_maxfailure;
  int pw_unlock;
  long pw_lockduration;
  long pw_resetfailurecount;
  int pw_gracelimit;
} passwdPolicy;

typedef struct _slapdFrontendConfig {
  rwl    *cfg_rwlock;       /* read/write lock to serialize access */
  struct pw_scheme *rootpwstoragescheme;
  int accesscontrol;
  int groupevalnestlevel;
  int idletimeout;
  int ioblocktimeout;
  int lastmod;
#if !defined(_WIN32) && !defined(AIX) 
  int maxdescriptors;
#endif /* !_WIN32 && !AIX */
  int conntablesize;
  int maxthreadsperconn;
  int outbound_ldap_io_timeout;
  int nagle;
  int port;
  int readonly;
  int reservedescriptors;
  int schemacheck;
  int ds4_compatible_schema;
  int schema_ignore_trailing_spaces;
  int secureport;
  int security;
  int SSLclientAuth;
  int ssl_check_hostname;
  int sizelimit;
  int SNMPenabled;
  char *SNMPdescription;
  char *SNMPorganization;
  char *SNMPlocation;
  char *SNMPcontact;
  int threadnumber;
  int timelimit;
  char *accesslog;
  struct berval **defaultreferral;
  char *encryptionalias;
  char *errorlog;
  char *listenhost;
#ifndef _WIN32
  char *localuser;
#endif /* _WIN32 */
  char *localhost;
  char *rootdn;
  char *rootpw;
  char *securelistenhost;
  char *srvtab;
  char *SSL3ciphers;
  char *userat;
  char *useroc;
  char *versionstring;
  char **backendconfig;
  char **include;
  char **plugin;
  struct pw_scheme *pw_storagescheme;

  int pwpolicy_local;
  int pw_is_global_policy;
  passwdPolicy pw_policy;

  /* ACCESS LOG */
  int  accesslog_logging_enabled;
  char *accesslog_mode;
  int  accesslog_maxnumlogs;
  int  accesslog_maxlogsize;
  int  accesslog_rotationsync_enabled;
  int  accesslog_rotationsynchour;
  int  accesslog_rotationsyncmin;
  int  accesslog_rotationtime;
  char *accesslog_rotationunit;
  int  accesslog_maxdiskspace;
  int  accesslog_minfreespace;
  int  accesslog_exptime;
  char *accesslog_exptimeunit;
  int	accessloglevel;
  int  accesslogbuffering;
  int  csnlogging;

   /* ERROR LOG */
  int errorlog_logging_enabled;
  char *errorlog_mode;
  int  errorlog_maxnumlogs;
  int  errorlog_maxlogsize;
  int  errorlog_rotationsync_enabled;
  int  errorlog_rotationsynchour;
  int  errorlog_rotationsyncmin;
  int  errorlog_rotationtime;
  char *errorlog_rotationunit;
  int  errorlog_maxdiskspace;
  int  errorlog_minfreespace;
  int  errorlog_exptime;
  char *errorlog_exptimeunit;
  int	errorloglevel;

  /* AUDIT LOG */
  char *auditlog;		/* replication audit file */
  int  auditloglevel;
  int  auditlog_logging_enabled;
  char *auditlog_mode;
  int  auditlog_maxnumlogs;
  int  auditlog_maxlogsize;
  int  auditlog_rotationsync_enabled;
  int  auditlog_rotationsynchour;
  int  auditlog_rotationsyncmin;
  int  auditlog_rotationtime;
  char *auditlog_rotationunit;
  int  auditlog_maxdiskspace;
  int  auditlog_minfreespace;
  int  auditlog_exptime;
  char *auditlog_exptimeunit;

  int return_exact_case;	/* Return attribute names with the same case 
				 * as they appear in at.conf */

  int result_tweak;
  char *refer_url;		/* for referral mode */
  int refer_mode;       /* for quick test */
  int	slapd_type;		/* Directory type; Full or Lite */
  
  ber_len_t maxbersize; /* Maximum BER element size we'll accept */
  int max_filter_nest_level;/* deepest nested filter we will accept */
  int enquote_sup_oc;       /* put single quotes around an oc's 
                               superior oc in cn=schema */

  char *certmap_basedn;	    /* Default Base DN for certmap */

  char *workingdir;	/* full path of directory before detach */
  char *configdir;  /* full path name of directory containing configuration files */
  char *schemadir;  /* full path name of directory containing schema files */
  char *lockdir;    /* full path name of directory containing lock files */
  char *tmpdir;     /* full path name of directory containing tmp files */
  char *certdir;    /* full path name of directory containing cert files */
  char *ldifdir;    /* full path name of directory containing ldif files */
  char *bakdir;     /* full path name of directory containing bakup files */
  char *rundir;     /* where pid, snmp stats, and ldapi files go */
  char *saslpath;   /* full path name of directory containing sasl plugins */
  int attrname_exceptions;  /* if true, allow questionable attribute names */
  int rewrite_rfc1274;		/* return attrs for both v2 and v3 names */
  char *schemareplace;		/* see CONFIG_SCHEMAREPLACE_* #defines below */
  char *ldapi_filename;		/* filename for ldapi socket */
  int ldapi_switch;             /* switch to turn ldapi on/off */
  int ldapi_bind_switch;        /* switch to turn ldapi auto binding on/off */
  char *ldapi_root_dn;          /* DN to map root to over LDAPI */
  int ldapi_map_entries;        /* turns ldapi entry bind mapping on/off */
  char *ldapi_uidnumber_type;   /* type that contains uid number */
  char *ldapi_gidnumber_type;   /* type that contains gid number */
  char *ldapi_search_base_dn;   /* base dn to search for mapped entries */
  char *ldapi_auto_dn_suffix;   /* suffix to be appended to auto gen DNs */
#ifndef _WIN32
  struct passwd *localuserinfo; /* userinfo of localuser */
#endif /* _WIN32 */
#ifdef MEMPOOL_EXPERIMENTAL
  int mempool_switch;           /* switch to turn memory pool on/off */
  int mempool_maxfreelist;      /* max free list length per memory pool item */
  long system_page_size;		/* system page size */
  int system_page_bits;			/* bit count to shift the system page size */
#endif /* MEMPOOL_EXPERIMENTAL */
} slapdFrontendConfig_t;

#define SLAPD_FULL	0
#define SLAPD_LITE	1

/* possible values for slapdFrontendConfig_t.schemareplace */
#define CONFIG_SCHEMAREPLACE_STR_OFF				"off"
#define CONFIG_SCHEMAREPLACE_STR_ON					"on"
#define CONFIG_SCHEMAREPLACE_STR_REPLICATION_ONLY	"replication-only"

 
slapdFrontendConfig_t *getFrontendConfig();

int slapd_bind_local_user(Connection *conn);

/* LP: NO_TIME cannot be -1, it generates wrong GeneralizedTime
 * And causes some errors on AIX also 
 */
/* #if defined( XP_WIN32 ) */
#define NO_TIME (time_t)0 /* cannot be -1, NT's localtime( -1 ) returns NULL */
/* #else */
/* #define NO_TIME (time_t)-1 / * a value that time() does not return  */
/* #endif */
#define NOT_FIRST_TIME (time_t)1 /* not the first logon */
#define SLAPD_END_TIME (time_t)2147483647  /* (2^31)-1, in 2038 */

extern char	*attr_dataversion;
#define	ATTR_DATAVERSION				"dataVersion"
#define ATTR_WITH_DIRSTRING_SYNTAX		"cn"

#define SLAPD_SNMP_UPDATE_INTERVAL (10 * 1000) /* 10 seconds */

#define LDAP_AUTH_KRBV41	0x81L
#define LDAP_AUTH_KRBV42	0x82L

/* for timing certain operations */
#ifdef USE_TIMERS

#ifndef _WIN32
#include <sys/time.h>
#ifdef LINUX
#define GTOD(t) gettimeofday(t, NULL)
#else
#define GTOD(t) gettimeofday(t)
#endif
#define TIMER_DECL(x)   struct timeval x##_start, x##_end
#define TIMER_START(x)  GTOD(&(x##_start))
#define TIMER_STOP(x)   GTOD(&(x##_end))
#define TIMER_GET_US(x) (unsigned)(((x##_end).tv_sec - (x##_start).tv_sec)  * 100000L + \
                         ((x##_end).tv_usec - (x##_start).tv_usec))
#else
#define TIMER_DECL(x)   LARGE_INTEGER x##_freq, x##_start, x##_end
#define TIMER_START(x)  do { \
    QueryPerformanceFrequency(&(x##_freq)); \
    QueryPerformanceCounter(&(x##_start)); \
} while(0)
#define TIMER_STOP(x)   QueryPerformanceCounter(&(x##_end))
#define TIMER_GET_US(x) (unsigned int)((x##_end.QuadPart - x##_start.QuadPart) / x##_freq.QuadPart)
#endif   /* _WIN32 */

#define TIMER_AVG_DECL(x) \
    TIMER_DECL(x); static unsigned int x##_total, x##_count
#define TIMER_AVG_START(x) \
    TIMER_START(x)
#define TIMER_AVG_STOP(x) do { \
    TIMER_STOP(x); \
    if (TIMER_GET_US(x) < 10000) { \
        x##_count++; \
        x##_total += TIMER_GET_US(x); \
    } \
} while (0)
#define TIMER_AVG_GET_US(x)     (unsigned int)(x##_total / x##_count)
#define TIMER_AVG_CHECK(x) do { \
    if (x##_count >= 1000) { \
        printf("timer %s: %d\n", #x, TIMER_AVG_GET_US(x)); \
        x##_total = x##_count = 0; \
    } \
} while (0)

#else

#define TIMER_DECL(x)
#define TIMER_START(x)
#define TIMER_STOP(x)
#define TIMER_GET_US(x) 0L
 
#endif   /* USE_TIMERS */
 
#define LDIF_CSNPREFIX_MAXLENGTH 6 /* sizeof(xxcsn-) */

#include "intrinsics.h"

/* printkey: import & export */
#define	EXPORT_PRINTKEY			0x1
#define	EXPORT_NOWRAP			0x2
#define	EXPORT_APPENDMODE		0x4
#define	EXPORT_MINIMAL_ENCODING	0x8
#define	EXPORT_ID2ENTRY_ONLY	0x10
#define	EXPORT_NOVERSION		0x20
#define	EXPORT_APPENDMODE_1		0x40
#define	EXPORT_INTERNAL			0x100

#define MTN_CONTROL_USE_ONE_BACKEND_OID	"2.16.840.1.113730.3.4.14"
#define MTN_CONTROL_USE_ONE_BACKEND_EXT_OID	"2.16.840.1.113730.3.4.20"

/* virtualListViewError is a relatively new concept that was added long 
 * after we implemented VLV. Until added to LDAP SDK, we define 
 * virtualListViewError here.  Once it's added, this define would go away. */
#ifndef LDAP_VIRTUAL_LIST_VIEW_ERROR
#define LDAP_VIRTUAL_LIST_VIEW_ERROR    0x4C      /* 76 */
#endif

#endif /* _slap_h_ */