mirror of
https://github.com/samba-team/samba.git
synced 2025-01-24 02:04:21 +03:00
s3: smbd: Make set_conn_connectpath() call canonicalize_absolute_path().
BUG: https://bugzilla.samba.org/show_bug.cgi?id=12531 Signed-off-by: Jeremy Allison <jra@samba.org> Reviewed-by: Uri Simchoni <uri@samba.org>
This commit is contained in:
parent
a51363309a
commit
d650d65488
@ -31,6 +31,7 @@
|
||||
#include "lib/param/loadparm.h"
|
||||
#include "messages.h"
|
||||
#include "lib/afs/afs_funcs.h"
|
||||
#include "lib/util_path.h"
|
||||
|
||||
static bool canonicalize_connect_path(connection_struct *conn)
|
||||
{
|
||||
@ -47,118 +48,20 @@ static bool canonicalize_connect_path(connection_struct *conn)
|
||||
/****************************************************************************
|
||||
Ensure when setting connectpath it is a canonicalized (no ./ // or ../)
|
||||
absolute path stating in / and not ending in /.
|
||||
Observent people will notice a similarity between this and check_path_syntax :-).
|
||||
****************************************************************************/
|
||||
|
||||
bool set_conn_connectpath(connection_struct *conn, const char *connectpath)
|
||||
{
|
||||
char *destname;
|
||||
char *d;
|
||||
const char *s = connectpath;
|
||||
bool start_of_name_component = true;
|
||||
|
||||
if (connectpath == NULL || connectpath[0] == '\0') {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Allocate for strlen + '\0' + possible leading '/' */
|
||||
destname = (char *)talloc_size(conn, strlen(connectpath) + 2);
|
||||
if (!destname) {
|
||||
destname = canonicalize_absolute_path(conn, connectpath);
|
||||
if (destname == NULL) {
|
||||
return false;
|
||||
}
|
||||
d = destname;
|
||||
|
||||
*d++ = '/'; /* Always start with root. */
|
||||
|
||||
while (*s) {
|
||||
if (*s == '/') {
|
||||
/* Eat multiple '/' */
|
||||
while (*s == '/') {
|
||||
s++;
|
||||
}
|
||||
if ((d > destname + 1) && (*s != '\0')) {
|
||||
*d++ = '/';
|
||||
}
|
||||
start_of_name_component = True;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (start_of_name_component) {
|
||||
if ((s[0] == '.') && (s[1] == '.') && (s[2] == '/' || s[2] == '\0')) {
|
||||
/* Uh oh - "/../" or "/..\0" ! */
|
||||
|
||||
/* Go past the ../ or .. */
|
||||
if (s[2] == '/') {
|
||||
s += 3;
|
||||
} else {
|
||||
s += 2; /* Go past the .. */
|
||||
}
|
||||
|
||||
/* If we just added a '/' - delete it */
|
||||
if ((d > destname) && (*(d-1) == '/')) {
|
||||
*(d-1) = '\0';
|
||||
d--;
|
||||
}
|
||||
|
||||
/* Are we at the start ? Can't go back further if so. */
|
||||
if (d <= destname) {
|
||||
*d++ = '/'; /* Can't delete root */
|
||||
continue;
|
||||
}
|
||||
/* Go back one level... */
|
||||
/* Decrement d first as d points to the *next* char to write into. */
|
||||
for (d--; d > destname; d--) {
|
||||
if (*d == '/') {
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* We're still at the start of a name component, just the previous one. */
|
||||
continue;
|
||||
} else if ((s[0] == '.') && ((s[1] == '\0') || s[1] == '/')) {
|
||||
/* Component of pathname can't be "." only - skip the '.' . */
|
||||
if (s[1] == '/') {
|
||||
s += 2;
|
||||
} else {
|
||||
s++;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (!(*s & 0x80)) {
|
||||
*d++ = *s++;
|
||||
} else {
|
||||
size_t siz;
|
||||
/* Get the size of the next MB character. */
|
||||
next_codepoint(s,&siz);
|
||||
switch(siz) {
|
||||
case 5:
|
||||
*d++ = *s++;
|
||||
/*fall through*/
|
||||
case 4:
|
||||
*d++ = *s++;
|
||||
/*fall through*/
|
||||
case 3:
|
||||
*d++ = *s++;
|
||||
/*fall through*/
|
||||
case 2:
|
||||
*d++ = *s++;
|
||||
/*fall through*/
|
||||
case 1:
|
||||
*d++ = *s++;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
start_of_name_component = false;
|
||||
}
|
||||
*d = '\0';
|
||||
|
||||
/* And must not end in '/' */
|
||||
if (d > destname + 1 && (*(d-1) == '/')) {
|
||||
*(d-1) = '\0';
|
||||
}
|
||||
|
||||
DEBUG(10,("set_conn_connectpath: service %s, connectpath = %s\n",
|
||||
lp_servicename(talloc_tos(), SNUM(conn)), destname ));
|
||||
|
Loading…
x
Reference in New Issue
Block a user