Line data Source code
1 : /*
2 : SSSD
3 :
4 : nscd.c
5 :
6 : Copyright (C) Jakub Hrozek <jhrozek@redhat.com> 2010
7 :
8 : This program is free software; you can redistribute it and/or modify
9 : it under the terms of the GNU General Public License as published by
10 : the Free Software Foundation; either version 3 of the License, or
11 : (at your option) any later version.
12 :
13 : This program is distributed in the hope that it will be useful,
14 : but WITHOUT ANY WARRANTY; without even the implied warranty of
15 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 : GNU General Public License for more details.
17 :
18 : You should have received a copy of the GNU General Public License
19 : along with this program. If not, see <http://www.gnu.org/licenses/>.
20 : */
21 :
22 : #include "config.h"
23 :
24 : #include <stdio.h>
25 : #include <talloc.h>
26 : #include <stdlib.h>
27 : #include <sys/types.h>
28 : #include <sys/wait.h>
29 :
30 : #include "util/util.h"
31 : #include "tools/tools_util.h"
32 :
33 : #ifndef NSCD_RELOAD_ARG
34 : #define NSCD_RELOAD_ARG "-i"
35 : #endif
36 :
37 : #if defined(NSCD_PATH) && defined(HAVE_NSCD)
38 0 : int flush_nscd_cache(enum nscd_db flush_db)
39 : {
40 : const char *service;
41 : pid_t nscd_pid;
42 : int ret, status;
43 :
44 0 : switch(flush_db) {
45 : case NSCD_DB_PASSWD:
46 0 : service = "passwd";
47 0 : break;
48 :
49 : case NSCD_DB_GROUP:
50 0 : service = "group";
51 0 : break;
52 :
53 : default:
54 0 : DEBUG(SSSDBG_CRIT_FAILURE, "Unknown nscd database\n");
55 0 : ret = EINVAL;
56 0 : goto done;
57 : }
58 :
59 0 : nscd_pid = fork();
60 0 : switch (nscd_pid) {
61 : case 0:
62 0 : execl(NSCD_PATH, NSCD_PATH, NSCD_RELOAD_ARG, service, NULL);
63 : /* if this returns it is an error */
64 0 : DEBUG(SSSDBG_CRIT_FAILURE,
65 : "execl(3) failed: %d(%s)\n", errno, strerror(errno));
66 0 : exit(errno);
67 : case -1:
68 0 : DEBUG(SSSDBG_CRIT_FAILURE, "fork failed\n");
69 0 : ret = EFAULT;
70 0 : break;
71 : default:
72 : do {
73 0 : errno = 0;
74 0 : ret = waitpid(nscd_pid, &status, 0);
75 0 : } while (ret == -1 && errno == EINTR);
76 0 : if (ret > 0) {
77 0 : if (WIFEXITED(status)) {
78 0 : ret = WEXITSTATUS(status);
79 0 : if (ret > 0) {
80 : /* The flush fails if nscd is not running, so do not care
81 : * about the return code */
82 0 : DEBUG(SSSDBG_TRACE_INTERNAL,
83 : "Error flushing cache, is nscd running?\n");
84 : }
85 : }
86 : } else {
87 0 : DEBUG(SSSDBG_FUNC_DATA,
88 : "Failed to wait for children %d\n", nscd_pid);
89 0 : ret = EIO;
90 : }
91 : }
92 :
93 : done:
94 0 : return ret;
95 : }
96 :
97 : #else /* defined(NSCD_PATH) && defined(HAVE_NSCD) */
98 : int flush_nscd_cache(enum nscd_db flush_db)
99 : {
100 : return EOK;
101 : }
102 : #endif
103 :
104 : /* NSCD config file parse and check */
105 :
106 0 : static unsigned int sss_nscd_check_service(char* svc_name)
107 : {
108 : struct sss_nscd_db {
109 : const char *svc_type_name;
110 : unsigned int nscd_service_flag;
111 : };
112 :
113 : int i;
114 0 : unsigned int ret = 0;
115 0 : struct sss_nscd_db db[] = {
116 : { "passwd", 0x0001 },
117 : { "group", 0x0010 },
118 : { "netgroup", 0x0100 },
119 : { "services", 0x1000 },
120 : { NULL, 0 }
121 : };
122 :
123 0 : if (svc_name == NULL) {
124 0 : return ret;
125 : }
126 :
127 0 : for (i = 0; db[i].svc_type_name != NULL; i++) {
128 0 : if (!strcmp(db[i].svc_type_name, svc_name)) {
129 :
130 0 : ret = db[i].nscd_service_flag;
131 0 : break;
132 : }
133 : }
134 :
135 0 : return ret;
136 : }
137 :
138 0 : errno_t sss_nscd_parse_conf(const char *conf_path)
139 : {
140 : FILE *fp;
141 0 : int ret = EOK;
142 0 : unsigned int occured = 0;
143 : char *line, *entry, *service, *enabled, *pad;
144 0 : size_t linelen = 0;
145 :
146 0 : fp = fopen(conf_path, "r");
147 0 : if (fp == NULL) {
148 0 : DEBUG(SSSDBG_MINOR_FAILURE, "Couldn't open NSCD configuration "
149 : "file [%s]\n", NSCD_CONF_PATH);
150 0 : return ENOENT;
151 : }
152 :
153 0 : while (getline(&line, &linelen, fp) != -1) {
154 :
155 0 : pad = strchr(line, '#');
156 0 : if (pad != NULL) {
157 0 : *pad = '\0';
158 : }
159 :
160 0 : if (line[0] == '\n' || line[0] == '\0') continue;
161 :
162 0 : entry = line;
163 0 : while (isspace(*entry) && *entry != '\0') {
164 0 : entry++;
165 : }
166 :
167 0 : pad = entry;
168 0 : while (!isspace(*pad) && *pad != '\0') {
169 0 : pad++;
170 : }
171 :
172 0 : service = pad;
173 0 : while (isspace(*service) && *service != '\0') {
174 0 : service++;
175 : }
176 :
177 0 : *pad = '\0';
178 0 : pad = service;
179 0 : while (!isspace(*pad) && *pad != '\0') {
180 0 : pad++;
181 : }
182 :
183 0 : enabled = pad;
184 0 : while (isspace(*enabled) && *enabled != '\0') {
185 0 : enabled++;
186 : }
187 :
188 0 : *pad = '\0';
189 0 : pad = enabled;
190 0 : while (!isspace(*pad) && *pad != '\0') {
191 0 : pad++;
192 : }
193 0 : *pad = '\0';
194 :
195 0 : if (!strcmp(entry, "enable-cache") &&
196 0 : !strcmp(enabled, "yes")) {
197 :
198 0 : occured |= sss_nscd_check_service(service);
199 : }
200 : };
201 :
202 0 : ret = ferror(fp);
203 0 : if (ret) {
204 0 : DEBUG(SSSDBG_MINOR_FAILURE, "Reading NSCD configuration file [%s] "
205 : "ended with failure [%d]: %s.\n",
206 : NSCD_CONF_PATH, ret, strerror(ret));
207 0 : ret = ENOENT;
208 0 : goto done;
209 : }
210 :
211 0 : ret = EOK;
212 0 : if (occured != 0) {
213 0 : ret = EEXIST;
214 0 : goto done;
215 : }
216 :
217 : done:
218 0 : free(line);
219 0 : fclose(fp);
220 :
221 0 : return ret;
222 : }
|