mirror of
https://github.com/samba-team/samba.git
synced 2024-12-23 17:34:34 +03:00
r640: Make cifsvfs symlinks work with paths within and external to the
share. Store external paths prefixed with smbln:. Jeremy.
This commit is contained in:
parent
86e78bf745
commit
14a9997b2e
@ -450,6 +450,7 @@ Offset Size Name
|
||||
#define CIFS_UNIX_FCNTL_LOCKS_CAP 0x1
|
||||
#define CIFS_UNIX_POSIX_ACLS_CAP 0x2
|
||||
|
||||
#define CIFS_CLIENT_SYMLINK_STRING "smbln:"
|
||||
/* ... more as we think of them :-). */
|
||||
|
||||
#endif
|
||||
|
@ -2762,6 +2762,7 @@ static int call_trans2qfilepathinfo(connection_struct *conn,
|
||||
case SMB_QUERY_FILE_UNIX_LINK:
|
||||
{
|
||||
pstring buffer;
|
||||
char *bufp = buffer;
|
||||
|
||||
DEBUG(10,("call_trans2qfilepathinfo: SMB_QUERY_FILE_UNIX_LINK\n"));
|
||||
#ifdef S_ISLNK
|
||||
@ -2774,7 +2775,11 @@ static int call_trans2qfilepathinfo(connection_struct *conn,
|
||||
if (len == -1)
|
||||
return(UNIXERROR(ERRDOS,ERRnoaccess));
|
||||
buffer[len] = 0;
|
||||
len = srvstr_push(outbuf, pdata, buffer, -1, STR_TERMINATE);
|
||||
if (strncmp(buffer, CIFS_CLIENT_SYMLINK_STRING, strlen(CIFS_CLIENT_SYMLINK_STRING)) == 0) {
|
||||
bufp += strlen(CIFS_CLIENT_SYMLINK_STRING);
|
||||
}
|
||||
|
||||
len = srvstr_push(outbuf, pdata, bufp, -1, STR_TERMINATE);
|
||||
pdata += len;
|
||||
data_size = PTR_DIFF(pdata,(*ppdata));
|
||||
|
||||
@ -2885,7 +2890,7 @@ static int ensure_link_is_safe(connection_struct *conn, const char *link_dest_in
|
||||
/* Store the UNIX converted path. */
|
||||
pstrcpy(link_dest_out, link_dest);
|
||||
|
||||
p = strrchr(link_dest, '/');
|
||||
p = strrchr_m(link_dest, '/');
|
||||
if (p) {
|
||||
fstrcpy(last_component, p+1);
|
||||
*p = '\0';
|
||||
@ -2897,6 +2902,9 @@ static int ensure_link_is_safe(connection_struct *conn, const char *link_dest_in
|
||||
if (SMB_VFS_REALPATH(conn,link_dest,resolved_name) == NULL)
|
||||
return -1;
|
||||
|
||||
DEBUG(10,("ensure_link_is_safe: realpath: link_dest (%s) -> real name (%s)\n",
|
||||
link_dest, resolved_name ));
|
||||
|
||||
pstrcpy(link_dest, resolved_name);
|
||||
pstrcat(link_dest, "/");
|
||||
pstrcat(link_dest, last_component);
|
||||
@ -2910,6 +2918,9 @@ static int ensure_link_is_safe(connection_struct *conn, const char *link_dest_in
|
||||
pstrcpy(link_test, link_dest);
|
||||
}
|
||||
|
||||
DEBUG(10,("ensure_link_is_safe: connectpath = %s, absolute resolved path = %s\n",
|
||||
conn->connectpath, link_test ));
|
||||
|
||||
/*
|
||||
* Check if the link is within the share.
|
||||
*/
|
||||
@ -3483,6 +3494,7 @@ size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n",
|
||||
{
|
||||
pstring oldname;
|
||||
char *newname = fname;
|
||||
BOOL cifs_client_link = False;
|
||||
|
||||
/* Set a symbolic link. */
|
||||
/* Don't allow this if follow links is false. */
|
||||
@ -3490,13 +3502,35 @@ size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n",
|
||||
if (!lp_symlinks(SNUM(conn)))
|
||||
return(ERROR_DOS(ERRDOS,ERRnoaccess));
|
||||
|
||||
srvstr_get_path(inbuf, oldname, pdata, sizeof(oldname), -1, STR_TERMINATE, &status);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
return ERROR_NT(status);
|
||||
srvstr_pull(inbuf, oldname, pdata, sizeof(oldname), -1, STR_TERMINATE);
|
||||
unix_format(oldname);
|
||||
|
||||
if (*oldname == '/') {
|
||||
/* Absolute paths are automatically a client resolved link. */
|
||||
cifs_client_link = True;
|
||||
} else {
|
||||
pstring rel_name;
|
||||
char *last_dirp = NULL;
|
||||
|
||||
pstrcpy(rel_name, newname);
|
||||
last_dirp = strrchr_m(rel_name, '/');
|
||||
if (last_dirp) {
|
||||
last_dirp[1] = '\0';
|
||||
} else {
|
||||
pstrcpy(rel_name, "./");
|
||||
}
|
||||
pstrcat(rel_name, oldname);
|
||||
if (ensure_link_is_safe(conn, rel_name, rel_name) != 0)
|
||||
cifs_client_link = True;
|
||||
|
||||
}
|
||||
|
||||
if (ensure_link_is_safe(conn, oldname, oldname) != 0)
|
||||
return(UNIXERROR(ERRDOS,ERRnoaccess));
|
||||
if (cifs_client_link) {
|
||||
pstring tmp_name;
|
||||
pstrcpy(tmp_name, CIFS_CLIENT_SYMLINK_STRING);
|
||||
pstrcat(tmp_name, oldname);
|
||||
pstrcpy(oldname, tmp_name);
|
||||
}
|
||||
|
||||
DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_LINK doing symlink %s -> %s\n",
|
||||
fname, oldname ));
|
||||
|
Loading…
Reference in New Issue
Block a user