1 /* $OpenLDAP$ */
2 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
3 *
4 * Copyright 1998-2021 The OpenLDAP Foundation.
5 * Portions Copyright 1998-2003 Kurt D. Zeilenga.
6 * Portions Copyright 2003 IBM Corporation.
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted only as authorized by the OpenLDAP
11 * Public License.
12 *
13 * A copy of this license is available in file LICENSE in the
14 * top-level directory of the distribution or, alternatively, at
15 * <http://www.OpenLDAP.org/license.html>.
16 */
17 /* ACKNOWLEDGEMENTS:
18 * This work was initially developed by Pierangelo Masarati for inclusion
19 * in OpenLDAP Software. Code portions borrowed from slapcat.c;
20 * contributors are Kurt Zeilenga and Jong Hyuk Choi
21 */
22
23 #include "portable.h"
24
25 #include <stdio.h>
26
27 #include "ac/stdlib.h"
28 #include "ac/ctype.h"
29 #include "ac/socket.h"
30 #include "ac/string.h"
31
32 #include "slapcommon.h"
33 #include "ldif.h"
34
35 static volatile sig_atomic_t gotsig;
36
37 static RETSIGTYPE
slapcat_sig(int sig)38 slapcat_sig( int sig )
39 {
40 gotsig=1;
41 }
42
43 int
slapschema(int argc,char ** argv)44 slapschema( int argc, char **argv )
45 {
46 ID id;
47 int rc = EXIT_SUCCESS;
48 const char *progname = "slapschema";
49 Connection conn = { 0 };
50 OperationBuffer opbuf;
51 Operation *op = NULL;
52 void *thrctx;
53 int requestBSF = 0;
54 int doBSF = 0;
55
56 slap_tool_init( progname, SLAPSCHEMA, argc, argv );
57
58 requestBSF = ( sub_ndn.bv_len || filter );
59
60 #ifdef SIGPIPE
61 (void) SIGNAL( SIGPIPE, slapcat_sig );
62 #endif
63 #ifdef SIGHUP
64 (void) SIGNAL( SIGHUP, slapcat_sig );
65 #endif
66 (void) SIGNAL( SIGINT, slapcat_sig );
67 (void) SIGNAL( SIGTERM, slapcat_sig );
68
69 if( !be->be_entry_open ||
70 !be->be_entry_close ||
71 !( be->be_entry_first || be->be_entry_first_x ) ||
72 !be->be_entry_next ||
73 !be->be_entry_get )
74 {
75 fprintf( stderr, "%s: database doesn't support necessary operations.\n",
76 progname );
77 exit( EXIT_FAILURE );
78 }
79
80 if( be->be_entry_open( be, 0 ) != 0 ) {
81 fprintf( stderr, "%s: could not open database.\n",
82 progname );
83 exit( EXIT_FAILURE );
84 }
85
86 thrctx = ldap_pvt_thread_pool_context();
87 connection_fake_init( &conn, &opbuf, thrctx );
88 op = &opbuf.ob_op;
89 op->o_tmpmemctx = NULL;
90 op->o_bd = be;
91
92
93 if ( !requestBSF && be->be_entry_first ) {
94 id = be->be_entry_first( be );
95
96 } else {
97 if ( be->be_entry_first_x ) {
98 id = be->be_entry_first_x( be,
99 sub_ndn.bv_len ? &sub_ndn : NULL, scope, filter );
100
101 } else {
102 assert( be->be_entry_first != NULL );
103 doBSF = 1;
104 id = be->be_entry_first( be );
105 }
106 }
107
108 for ( ; id != NOID; id = be->be_entry_next( be ) ) {
109 Entry* e;
110 char textbuf[SLAP_TEXT_BUFLEN];
111 size_t textlen = sizeof(textbuf);
112 const char *text = NULL;
113
114 if ( gotsig )
115 break;
116
117 e = be->be_entry_get( be, id );
118 if ( e == NULL ) {
119 printf("# no data for entry id=%08lx\n\n", (long) id );
120 rc = EXIT_FAILURE;
121 if( continuemode ) continue;
122 break;
123 }
124
125 if ( doBSF ) {
126 if ( sub_ndn.bv_len && !dnIsSuffixScope( &e->e_nname, &sub_ndn, scope ) )
127 {
128 be_entry_release_r( op, e );
129 continue;
130 }
131
132
133 if ( filter != NULL ) {
134 int rc = test_filter( NULL, e, filter );
135 if ( rc != LDAP_COMPARE_TRUE ) {
136 be_entry_release_r( op, e );
137 continue;
138 }
139 }
140 }
141
142 if( verbose ) {
143 printf( "# id=%08lx\n", (long) id );
144 }
145
146 rc = entry_schema_check( op, e, NULL, 0, 0, NULL,
147 &text, textbuf, textlen );
148 if ( rc != LDAP_SUCCESS ) {
149 fprintf( ldiffp->fp, "# (%d) %s%s%s\n",
150 rc, ldap_err2string( rc ),
151 text ? ": " : "",
152 text ? text : "" );
153 fprintf( ldiffp->fp, "dn: %s\n\n", e->e_name.bv_val );
154 }
155
156 be_entry_release_r( op, e );
157 }
158
159 be->be_entry_close( be );
160
161 if ( slap_tool_destroy() )
162 rc = EXIT_FAILURE;
163
164 return rc;
165 }
166