xref: /netbsd-src/external/bsd/openldap/dist/servers/slapd/slapschema.c (revision 549b59ed3ccf0d36d3097190a0db27b770f3a839)
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