1 /* usmb - mount SMB shares via FUSE and Samba
2 * Copyright (C) 2006-2010 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/>.
23 #include <sys/types.h>
31 #include "config.rng.h"
34 static bool check_conf_perms (const char *conffile
, int fd
)
38 if (0 == fstat (fd
, &buf
))
40 if (getuid() != buf
.st_uid
)
42 fprintf (stderr
, "You do not own the configuration file %s.\n", conffile
);
46 if (buf
.st_mode
& (S_IRWXG
| S_IRWXO
))
48 fprintf (stderr
, "Configuration file %s is accessible to non-owner.\n",
56 fprintf (stderr
, "Cannot stat configuration file %s: %s.\n",
57 conffile
, strerror (errno
));
65 static bool conffile_read (const char *filename
,
67 xmlXPathContextPtr
*ctx
)
69 int fd
= open (filename
, O_RDONLY
);
72 fprintf (stderr
, "Cannot open %s: %s.\n", filename
, strerror (errno
));
76 if (!check_conf_perms (filename
, fd
))
82 *doc
= xmlReadFd (fd
, NULL
, NULL
, XML_PARSE_NONET
);
87 fprintf (stderr
, "Cannot parse %s.\n", filename
);
91 if (!xml_validate_relaxng (*doc
, rng_config
))
93 fprintf (stderr
, "%s isn't a valid USMB configuration.\n", filename
);
98 *ctx
= xmlXPathNewContext (*doc
);
101 fputs ("Cannot create XPath context.\n", stderr
);
110 static bool do_xpath_text (xmlXPathContextPtr ctx
,
111 const char *parent
, const char *id
,
112 const char *child
, char **out
)
116 if (!bsnprintf (xpath
, sizeof (xpath
),
117 "/usmbconfig/%s[@id='%s']/%s/text()", parent
, id
, child
))
120 return xml_xpath_text (ctx
, xpath
, (void *)out
);
124 // Expand ~ in *mountpoint.
125 static bool expand_tilde (char **mountpoint
)
127 assert (NULL
!= mountpoint
);
128 assert (NULL
!= *mountpoint
);
130 if ('~' != **mountpoint
)
133 // Extract the username.
134 char * const username
= (*mountpoint
) + 1;
135 char * const end
= strchr (username
, '/');
137 const char *dir
= NULL
;
139 if (('\0' == *username
) || (end
== username
)) // No username => use HOME.
141 dir
= getenv ("HOME");
143 else // Else look up the user's home directory.
148 struct passwd
* const pwd
= getpwnam (username
);
158 fputs ("Failed to expand tilde in mount point.\n", stderr
);
163 if (!baprintf (&result
, "%s%s", dir
, (NULL
== end
) ? "" : end
))
165 perror ("Failed to expand tilde in mount point");
170 *mountpoint
= result
;
175 bool conffile_get_mount (const char *filename
, const char *key
,
176 char **server
, char **share
,
177 char **mountpoint
, char **options
,
178 char **domain
, char **username
,
182 xmlXPathContextPtr ctx
;
186 *server
= *share
= *mountpoint
= *options
= NULL
;
187 *domain
= *username
= *password
= NULL
;
189 if (strchr (key
, '\''))
191 fprintf (stderr
, "Invalid share name: %s.\n", key
);
195 if (!conffile_read (filename
, &doc
, &ctx
))
199 if (!do_xpath_text (ctx
, "mount", key
, "server", server
)) break;
200 if (!do_xpath_text (ctx
, "mount", key
, "share", share
)) break;
201 if (!do_xpath_text (ctx
, "mount", key
, "mountpoint", mountpoint
)) break;
202 if (!expand_tilde (mountpoint
)) break;
203 (void)do_xpath_text (ctx
, "mount", key
, "options", options
);
205 if (!snprintf (xp
, sizeof (xp
), "/usmbconfig/mount[@id='%s']", key
)) break;
206 if (!xml_xpath_attr_value (ctx
, xp
, "credentials", &creds
)) break;
208 (void)do_xpath_text (ctx
, "credentials", creds
, "domain", domain
);
209 if (!do_xpath_text (ctx
, "credentials", creds
, "username", username
)) break;
211 if (!do_xpath_text (ctx
, "credentials", creds
, "password", password
))
214 xmlXPathFreeContext (ctx
);
219 } while (false /*CONSTCOND*/);
221 fputs ("Invalid configuration.\n", stderr
);
224 clear_and_free (*password
);
232 xmlXPathFreeContext (ctx
);