]> git.sur5r.net Git - openldap/blob - servers/slurpd/sanity.c
Import ITS#3764 from HEAD
[openldap] / servers / slurpd / sanity.c
1 /* $OpenLDAP$ */
2 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
3  *
4  * Copyright 1998-2005 The OpenLDAP Foundation.
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted only as authorized by the OpenLDAP
9  * Public License.
10  *
11  * A copy of this license is available in file LICENSE in the
12  * top-level directory of the distribution or, alternatively, at
13  * <http://www.OpenLDAP.org/license.html>.
14  */
15 /* Portions Copyright (c) 1996 Regents of the University of Michigan.
16  * All rights reserved.
17  *
18  * Redistribution and use in source and binary forms are permitted
19  * provided that this notice is preserved and that due credit is given
20  * to the University of Michigan at Ann Arbor. The name of the University
21  * may not be used to endorse or promote products derived from this
22  * software without specific prior written permission. This software
23  * is provided ``as is'' without express or implied warranty.
24  */
25 /* ACKNOWLEDGEMENTS:
26  * This work was originally developed by the University of Michigan
27  * (as part of U-MICH LDAP).
28  */
29
30
31 /*
32  * sanity.c - perform sanity checks on the environment at startup time,
33  * and report any errors before we disassociate from the controlling tty,
34  * start up our threads, and do other stuff which makes it hard to give
35  * feedback to the users.
36  */
37
38 #include "portable.h"
39
40 #include <stdio.h>
41
42 #include <ac/stdlib.h>
43 #include <ac/unistd.h>
44 #include <ac/string.h>
45
46 #include "slurp.h"
47 #include "globals.h"
48
49 #define FC_DIRBAD       1
50 #define FC_DIRUNREAD    2
51 #define FC_DIRUNWRITE   4
52 #define FC_FILEBAD      8
53 #define FC_FILEUNREAD   16
54 #define FC_FILEUNWRITE  32
55
56
57 /*
58  * Forward declarations
59  */
60 static unsigned int filecheck LDAP_P(( char * ));
61
62
63
64 /*
65  * Take a look around to catch any fatal errors.  For example, make sure the
66  * destination directory for our working files exists, check that all
67  * pathnames make sense, and so on.  Returns 0 is everything's ok,
68  # -1 if there's something wrong which will keep us from functioning
69  * correctly.
70  *
71  * We do all these checks at startup so we can print a reasonable error
72  * message on stderr before we disassociate from the controlling tty.  This
73  * keeps some fatal error messages from "disappearing" into syslog.
74  */
75
76 int
77 sanity( void )
78 {
79     int err = 0;
80     int rc;
81
82     /*
83      * Are there any replicas listed in the slapd config file?
84      */
85     if ( sglob->replicas == NULL ) {
86         fprintf( stderr, "No replicas in slapd.conf file \"%s\"!\n",
87             sglob->slapd_configfile );
88         err++;
89     }
90
91     /*
92      * Make sure the directory housing the slapd replogfile exists, and
93      * that the slapd replogfile is readable, if it exists.
94      */
95     if ( sglob->slapd_replogfile == NULL ) {
96         fprintf( stderr, "Fatal error: no \"replogfile\" "
97                 "slapd.conf directive given\n" );
98         err++;
99     } else {
100         rc = filecheck( sglob->slapd_replogfile );
101         if ( rc & FC_DIRBAD ) {
102             fprintf( stderr, "Error: %s: directory specified in "
103                         "\"replogfile\" slapd.conf directive does not exist\n", 
104                     sglob->slapd_replogfile );
105             err++;
106         } else if ( rc & FC_DIRUNREAD ) {
107             fprintf( stderr, "Error: %s: directory specified in "
108                         "\"replogfile\" slapd.conf directive is not readable\n", 
109                     sglob->slapd_replogfile );
110             err++;
111         } else if (!( rc & FC_FILEBAD) && ( rc & FC_FILEUNREAD )) {
112             fprintf( stderr, "Error: %s: file specified in "
113                         "\"replogfile\" slapd.conf directive is not readable\n", 
114                     sglob->slapd_replogfile );
115             err++;
116         }
117     }
118
119     /*
120      * Make sure the directory for the slurpd replogfile is there, and
121      * that the slurpd replogfile is readable and writable, if it exists.
122      */
123     if ( sglob->slurpd_replogfile == NULL ) {
124         fprintf( stderr, "Fatal error: no \"replogfile\" directive given\n" );
125         err++;
126     } else {
127         rc = filecheck( sglob->slurpd_replogfile );
128         if ( rc & FC_DIRBAD ) {
129             fprintf( stderr, "Error: %s: slurpd \"replogfile\" "
130                         "directory does not exist\n", 
131                     sglob->slurpd_replogfile );
132             err++;
133         } else if ( rc & FC_DIRUNREAD ) {
134             fprintf( stderr, "Error: %s: slurpd \"replogfile\" "
135                         "directory not readable\n", 
136                     sglob->slurpd_replogfile );
137             err++;
138         } else if ( !( rc & FC_FILEBAD ) && ( rc & FC_FILEUNREAD )) {
139             fprintf( stderr, "Error: %s: slurpd \"replogfile\" not readable\n", 
140                     sglob->slurpd_replogfile );
141             err++;
142         } else if ( !( rc & FC_FILEBAD ) && ( rc & FC_FILEUNWRITE )) {
143             fprintf( stderr, "Error: %s: slurpd \"replogfile\" not writeable\n", 
144                     sglob->slurpd_replogfile );
145             err++;
146         }
147     }
148
149     /*
150      * Make sure that the directory for the slurpd status file is there, and
151      * that the slurpd status file is writable, if it exists.
152      */
153     rc = filecheck( sglob->slurpd_status_file );
154     if ( rc & FC_DIRBAD ) {
155         fprintf( stderr, "Error: %s: status directory does not exist\n", 
156                 sglob->slurpd_status_file );
157         err++;
158     } else if ( rc & FC_DIRUNREAD ) {
159         fprintf( stderr, "Error: %s: status directory not readable\n", 
160                 sglob->slurpd_status_file );
161         err++;
162     } else if ( !( rc & FC_FILEBAD ) && ( rc & FC_FILEUNREAD )) {
163         fprintf( stderr, "Error: %s: status file not readable\n", 
164                 sglob->slurpd_status_file );
165         err++;
166     } else if ( !( rc & FC_FILEBAD ) && ( rc & FC_FILEUNWRITE )) {
167         fprintf( stderr, "Error: %s: status file not writeable\n", 
168                 sglob->slurpd_status_file );
169         err++;
170     }
171     
172     return ( err == 0 ? 0 : -1 );
173 }
174
175
176
177 /*
178  * Check for the existence of the file and directory leading to the file.
179  * Returns a bitmask which is the logical OR of the following flags:
180  *
181  *  FC_DIRBAD:          directory containing "f" does not exist.
182  *  FC_DIRUNREAD:       directory containing "f" exists but is not readable.
183  *  FC_DIRUNWRITE:      directory containing "f" exists but is not writable.
184  *  FC_FILEBAD:         "f" does not exist.
185  *  FC_FILEUNREAD:      "f" exists but is unreadable.
186  *  FC_FILEUNWRITE:     "f" exists but is unwritable.
187  *
188  * The calling routine is responsible for determining which, if any, of
189  * the returned flags is a problem for a particular file.
190  */
191 static unsigned int
192 filecheck(
193     char        *f
194 )
195 {
196     char                dir[ MAXPATHLEN ];
197     char                *p;
198     unsigned int        ret = 0;
199
200         snprintf( dir, sizeof dir, "%s", f );
201     p = strrchr( dir, LDAP_DIRSEP[0] );
202     if ( p != NULL ) {
203         *p = '\0';
204     }
205     if ( access( dir, F_OK ) < 0 ) {
206         ret |= FC_DIRBAD;
207     }
208     if ( access( dir, R_OK ) < 0 ) {
209         ret |= FC_DIRUNREAD;
210     }
211     if ( access( dir, W_OK ) < 0 ) {
212         ret |= FC_DIRUNWRITE;
213     }
214     if ( access( f, F_OK ) < 0 ) {
215         ret |= FC_FILEBAD;
216     }
217     if ( access( f, R_OK ) < 0 ) {
218         ret |= FC_FILEUNREAD;
219     }
220     if ( access( f, W_OK ) < 0 ) {
221         ret |= FC_FILEUNWRITE;
222     }
223
224     return ret;
225 }