diff options
author | Jeremy Allison <jra@samba.org> | 2017-01-17 11:35:52 -0800 |
---|---|---|
committer | Jeremy Allison <jra@samba.org> | 2017-01-30 18:39:18 +0100 |
commit | d650d65488761b30fa34d42cb1ab400618a78c33 (patch) | |
tree | e84e72353ee03e5e7b209d65caf2e3041e8507da /source3/smbd/service.c | |
parent | a51363309a4330b65e34ae941ec99d180bdbab56 (diff) | |
download | samba-d650d65488761b30fa34d42cb1ab400618a78c33.tar.gz |
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>
Diffstat (limited to 'source3/smbd/service.c')
-rw-r--r-- | source3/smbd/service.c | 103 |
1 files changed, 3 insertions, 100 deletions
diff --git a/source3/smbd/service.c b/source3/smbd/service.c index ce4b8da1e24..0376a330e23 100644 --- a/source3/smbd/service.c +++ b/source3/smbd/service.c @@ -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 )); |