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