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