Cosmetic improvements.
[usmb.git] / conffile.c
blob5388ee9734678626f4f40b8f265fcba3fff37d53
1 /* usmb - mount SMB shares via FUSE and Samba
2 * Copyright (C) 2006-2008 Geoff Johnstone
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 3 as
6 * published by the Free Software Foundation.
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 #include <assert.h>
18 #include <errno.h>
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include <string.h>
22 #include <sys/types.h>
23 #include <sys/stat.h>
24 #include <fcntl.h>
25 #include <unistd.h>
26 #include "password.h"
27 #include "utils.h"
28 #include "xml.h"
29 #include "config.rng.h"
32 static bool check_conf_perms (const char *conffile, int fd)
34 struct stat buf;
36 if (0 == fstat (fd, &buf))
38 if (getuid() != buf.st_uid)
40 fprintf (stderr, "You do not own the configuration file %s.\n", conffile);
41 return false;
44 if (buf.st_mode & (S_IRWXG | S_IRWXO))
46 fprintf (stderr, "Configuration file %s is accessible to non-owner.\n",
47 conffile);
48 return false;
52 else
54 fprintf (stderr, "Cannot stat configuration file %s: %s.\n",
55 conffile, strerror (errno));
56 return false;
59 return true;
63 static bool conffile_read (const char *filename,
64 xmlDocPtr *doc,
65 xmlXPathContextPtr *ctx)
67 int fd = open (filename, O_RDONLY);
68 if (-1 == fd)
70 fprintf (stderr, "Cannot open %s: %s.\n", filename, strerror (errno));
71 return false;
74 if (!check_conf_perms (filename, fd))
76 (void)close (fd);
77 return false;
80 *doc = xmlReadFd (fd, NULL, NULL, XML_PARSE_NONET);
81 (void)close (fd);
83 if (NULL == *doc)
85 fprintf (stderr, "Cannot parse %s.\n", filename);
86 return false;
89 if (!xml_validate_relaxng (*doc, rng_config))
91 fprintf (stderr, "%s isn't a valid USMB configuration.\n", filename);
92 xmlFreeDoc (*doc);
93 return false;
96 *ctx = xmlXPathNewContext (*doc);
97 if (NULL == *ctx)
99 fputs ("Cannot create XPath context.\n", stderr);
100 xmlFreeDoc (*doc);
101 return false;
104 return true;
108 static bool do_xpath_text (xmlXPathContextPtr ctx,
109 const char *parent, const char *id,
110 const char *child, char **out)
112 char xpath[2048];
113 snprintf (xpath, sizeof (xpath),
114 "/usmbconfig/%s[@id='%s']/%s/text()", parent, id, child);
115 return xml_xpath_text (ctx, xpath, (void *)out);
119 bool conffile_get_mount (const char *filename, const char *key,
120 char **server, char **share,
121 char **mountpoint, char **options,
122 char **domain, char **username,
123 char **password)
125 xmlDocPtr doc;
126 xmlXPathContextPtr ctx;
127 char xp[2048];
128 char *creds = NULL;
130 *server = *share = *mountpoint = *options = NULL;
131 *domain = *username = *password = NULL;
133 if (strchr (key, '\''))
135 fprintf (stderr, "Invalid share name: %s.\n", key);
136 return false;
139 if (!conffile_read (filename, &doc, &ctx))
140 return false;
142 do {
143 if (!do_xpath_text (ctx, "mount", key, "server", server)) break;
144 if (!do_xpath_text (ctx, "mount", key, "share", share)) break;
145 if (!do_xpath_text (ctx, "mount", key, "mountpoint", mountpoint)) break;
146 (void)do_xpath_text (ctx, "mount", key, "options", options);
148 snprintf (xp, sizeof (xp), "/usmbconfig/mount[@id='%s']", key);
149 if (!xml_xpath_attr_value (ctx, xp, "credentials", &creds)) break;
151 (void)do_xpath_text (ctx, "credentials", creds, "domain", domain);
152 if (!do_xpath_text (ctx, "credentials", creds, "username", username)) break;
154 if (!do_xpath_text (ctx, "credentials", creds, "password", password) &&
155 !password_read (password))
156 break;
158 xmlXPathFreeContext (ctx);
159 xmlFreeDoc (doc);
161 return true;
162 /*NOTREACHED*/
163 } while (false /*CONSTCOND*/);
165 fputs ("Invalid configuration.\n", stderr);
167 xfree (*username);
168 clear_and_free (*password);
169 xfree (*domain);
170 xfree (creds);
171 xfree (*options);
172 xfree (*mountpoint);
173 xfree (*share);
174 xfree (*server);
176 xmlXPathFreeContext (ctx);
177 xmlFreeDoc (doc);
179 return false;