*/
#include "includes.h"
+#include "system/filesys.h"
#include "version.h"
+#include "smbd/smbd.h"
#include "smbd/globals.h"
#include "../libcli/auth/libcli_auth.h"
#include "../librpc/gen_ndr/xattr.h"
#include "../librpc/gen_ndr/ndr_security.h"
+#include "../librpc/gen_ndr/open_files.h"
#include "libcli/security/security.h"
+#include "trans2.h"
+#include "auth.h"
+#include "smbprofile.h"
+#include "rpc_server/srv_pipe_hnd.h"
+#include "printing.h"
#define DIR_ENTRY_SAFETY_MARGIN 4096
files_struct *fsp,
const SMB_STRUCT_STAT *psbuf);
+/********************************************************************
+ The canonical "check access" based on object handle or path function.
+********************************************************************/
+
+NTSTATUS check_access(connection_struct *conn,
+ files_struct *fsp,
+ const struct smb_filename *smb_fname,
+ uint32_t access_mask)
+{
+ if (fsp) {
+ if (!(fsp->access_mask & access_mask)) {
+ return NT_STATUS_ACCESS_DENIED;
+ }
+ } else {
+ NTSTATUS status = smbd_check_access_rights(conn,
+ smb_fname,
+ false,
+ access_mask);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+ }
+ return NT_STATUS_OK;
+}
+
/********************************************************************
Roundup a value to the nearest allocation roundup size boundary.
Only do this for Windows clients.
if (strequal( prohibited_ea_names[i], unix_ea_name))
return true;
}
- if (StrnCaseCmp(unix_ea_name, SAMBA_XATTR_DOSSTREAM_PREFIX,
+ if (strncasecmp_m(unix_ea_name, SAMBA_XATTR_DOSSTREAM_PREFIX,
strlen(SAMBA_XATTR_DOSSTREAM_PREFIX)) == 0) {
return true;
}
again:
- val = TALLOC_REALLOC_ARRAY(mem_ctx, val, char, attr_size);
+ val = talloc_realloc(mem_ctx, val, char, attr_size);
if (!val) {
return NT_STATUS_NO_MEMORY;
}
* TALLOC the result early to get the talloc hierarchy right.
*/
- names = TALLOC_ARRAY(mem_ctx, char *, 1);
+ names = talloc_array(mem_ctx, char *, 1);
if (names == NULL) {
DEBUG(0, ("talloc failed\n"));
return NT_STATUS_NO_MEMORY;
while (ea_namelist_size <= 65536) {
- ea_namelist = TALLOC_REALLOC_ARRAY(
+ ea_namelist = talloc_realloc(
names, ea_namelist, char, ea_namelist_size);
if (ea_namelist == NULL) {
DEBUG(0, ("talloc failed\n"));
num_names += 1;
}
- tmp = TALLOC_REALLOC_ARRAY(mem_ctx, names, char *, num_names);
+ tmp = talloc_realloc(mem_ctx, names, char *, num_names);
if (tmp == NULL) {
DEBUG(0, ("talloc failed\n"));
TALLOC_FREE(names);
Return a linked list of the total EA's. Plus the total size
****************************************************************************/
-static struct ea_list *get_ea_list_from_file(TALLOC_CTX *mem_ctx, connection_struct *conn, files_struct *fsp,
- const char *fname, size_t *pea_total_len)
+static NTSTATUS get_ea_list_from_file_path(TALLOC_CTX *mem_ctx, connection_struct *conn, files_struct *fsp,
+ const char *fname, size_t *pea_total_len, struct ea_list **ea_list)
{
/* Get a list of all xattrs. Max namesize is 64k. */
size_t i, num_names;
*pea_total_len = 0;
- if (!lp_ea_support(SNUM(conn))) {
- return NULL;
- }
-
status = get_ea_names_from_file(talloc_tos(), conn, fsp, fname,
&names, &num_names);
- if (!NT_STATUS_IS_OK(status) || (num_names == 0)) {
- return NULL;
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
+ if (num_names == 0) {
+ *ea_list = NULL;
+ return NT_STATUS_OK;
}
for (i=0; i<num_names; i++) {
|| samba_private_attr_name(names[i]))
continue;
- listp = TALLOC_P(mem_ctx, struct ea_list);
+ listp = talloc(mem_ctx, struct ea_list);
if (listp == NULL) {
- return NULL;
+ return NT_STATUS_NO_MEMORY;
}
- if (!NT_STATUS_IS_OK(get_ea_value(mem_ctx, conn, fsp,
- fname, names[i],
- &listp->ea))) {
- return NULL;
+ status = get_ea_value(mem_ctx, conn, fsp,
+ fname, names[i],
+ &listp->ea);
+
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
}
push_ascii_fstring(dos_ea_name, listp->ea.name);
DEBUG(10, ("get_ea_list_from_file: total_len = %u\n",
(unsigned int)*pea_total_len));
- return ea_list_head;
+ *ea_list = ea_list_head;
+ return NT_STATUS_OK;
+}
+
+static NTSTATUS get_ea_list_from_file(TALLOC_CTX *mem_ctx, connection_struct *conn, files_struct *fsp,
+ const struct smb_filename *smb_fname, size_t *pea_total_len, struct ea_list **ea_list)
+{
+ *pea_total_len = 0;
+ *ea_list = NULL;
+
+ if (!lp_ea_support(SNUM(conn))) {
+ return NT_STATUS_OK;
+ }
+
+ if (is_ntfs_stream_smb_fname(smb_fname)) {
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+
+ return get_ea_list_from_file_path(mem_ctx, conn, fsp, smb_fname->base_name, pea_total_len, ea_list);
}
/****************************************************************************
SCVAL(p,0,ea_list->ea.flags);
SCVAL(p,1,dos_namelen);
SSVAL(p,2,ea_list->ea.value.length);
- fstrcpy(p+4, dos_ea_name);
+ strlcpy(p+4, dos_ea_name, dos_namelen+1);
memcpy( p + 4 + dos_namelen + 1, ea_list->ea.value.data, ea_list->ea.value.length);
total_data_size -= 4 + dos_namelen + 1 + ea_list->ea.value.length;
SCVAL(p, 0x04, ea_list->ea.flags);
SCVAL(p, 0x05, dos_namelen);
SSVAL(p, 0x06, ea_list->ea.value.length);
- fstrcpy((char *)(p+0x08), dos_ea_name);
+ strlcpy((char *)(p+0x08), dos_ea_name, dos_namelen+1);
memcpy(p + 0x08 + dos_namelen + 1, ea_list->ea.value.data, ea_list->ea.value.length);
total_data_size -= this_size;
return NT_STATUS_OK;
}
-static unsigned int estimate_ea_size(connection_struct *conn, files_struct *fsp, const char *fname)
+static unsigned int estimate_ea_size(connection_struct *conn, files_struct *fsp, const struct smb_filename *smb_fname)
{
size_t total_ea_len = 0;
- TALLOC_CTX *mem_ctx = NULL;
+ TALLOC_CTX *mem_ctx;
+ struct ea_list *ea_list;
if (!lp_ea_support(SNUM(conn))) {
return 0;
}
- mem_ctx = talloc_tos();
- (void)get_ea_list_from_file(mem_ctx, conn, fsp, fname, &total_ea_len);
+ mem_ctx = talloc_stackframe();
+
+ /* If this is a stream fsp, then we need to instead find the
+ * estimated ea len from the main file, not the stream
+ * (streams cannot have EAs), but the estimate isn't just 0 in
+ * this case! */
+ if (is_ntfs_stream_smb_fname(smb_fname)) {
+ fsp = NULL;
+ }
+ (void)get_ea_list_from_file_path(mem_ctx, conn, fsp, smb_fname->base_name, &total_ea_len, &ea_list);
+ TALLOC_FREE(mem_ctx);
return total_ea_len;
}
{
size_t total_ea_len;
TALLOC_CTX *mem_ctx = talloc_tos();
- struct ea_list *ea_list = get_ea_list_from_file(mem_ctx, conn, fsp, fname, &total_ea_len);
+ struct ea_list *ea_list;
+ NTSTATUS status = get_ea_list_from_file_path(mem_ctx, conn, fsp, fname, &total_ea_len, &ea_list);
+ if (!NT_STATUS_IS_OK(status)) {
+ return;
+ }
for (; ea_list; ea_list = ea_list->next) {
if (strequal(&unix_ea_name[5], ea_list->ea.name)) {
DEBUG(10,("canonicalize_ea_name: %s -> %s\n",
&unix_ea_name[5], ea_list->ea.name));
- safe_strcpy(&unix_ea_name[5], ea_list->ea.name, sizeof(fstring)-6);
+ strlcpy(&unix_ea_name[5], ea_list->ea.name, sizeof(fstring)-5);
break;
}
}
NTSTATUS set_ea(connection_struct *conn, files_struct *fsp,
const struct smb_filename *smb_fname, struct ea_list *ea_list)
{
+ NTSTATUS status;
char *fname = NULL;
if (!lp_ea_support(SNUM(conn))) {
return NT_STATUS_EAS_NOT_SUPPORTED;
}
- /* For now setting EAs on streams isn't supported. */
+ status = check_access(conn, fsp, smb_fname, FILE_WRITE_EA);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
+ /* Setting EAs on streams isn't supported. */
+ if (is_ntfs_stream_smb_fname(smb_fname)) {
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+
fname = smb_fname->base_name;
for (;ea_list; ea_list = ea_list->next) {
size_t converted_size, offset = 0;
while (offset + 2 < data_size) {
- struct ea_list *eal = TALLOC_ZERO_P(ctx, struct ea_list);
+ struct ea_list *eal = talloc_zero(ctx, struct ea_list);
unsigned int namelen = CVAL(pdata,offset);
offset++; /* Go past the namelen byte. */
struct ea_list *read_ea_list_entry(TALLOC_CTX *ctx, const char *pdata, size_t data_size, size_t *pbytes_used)
{
- struct ea_list *eal = TALLOC_ZERO_P(ctx, struct ea_list);
+ struct ea_list *eal = talloc_zero(ctx, struct ea_list);
uint16 val_len;
unsigned int namelen;
size_t converted_size;
reply_outbuf(req, 10, total_sent_thistime + alignment_offset
+ data_alignment_offset);
- /*
- * We might have SMBtrans2s in req which was transferred to
- * the outbuf, fix that.
- */
- SCVAL(req->outbuf, smb_com, SMBtrans2);
-
/* Set total params and data to be sent */
SSVAL(req->outbuf,smb_tprcnt,paramsize);
SSVAL(req->outbuf,smb_tdrcnt,datasize);
uint32 open_size;
char *pname;
char *fname = NULL;
- SMB_OFF_T size=0;
+ off_t size=0;
int fattr=0,mtime=0;
SMB_INO_T inode = 0;
int smb_action = 0;
goto out;
}
- if (!map_open_params_to_ntcreate(smb_fname, deny_mode, open_ofun,
+ if (!map_open_params_to_ntcreate(smb_fname->base_name, deny_mode,
+ open_ofun,
&access_mask, &share_mode,
&create_disposition,
&create_options,
&smb_action); /* psbuf */
if (!NT_STATUS_IS_OK(status)) {
- if (open_was_deferred(req->mid)) {
+ if (open_was_deferred(req->sconn, req->mid)) {
/* We have re-scheduled this call. */
goto out;
}
fattr = dos_mode(conn, smb_fname);
mtime = convert_timespec_to_time_t(smb_fname->st.st_ex_mtime);
inode = smb_fname->st.st_ex_ino;
- if (fattr & aDIR) {
+ if (fattr & FILE_ATTRIBUTE_DIRECTORY) {
close_file(req, fsp, ERROR_CLOSE);
reply_nterror(req, NT_STATUS_ACCESS_DENIED);
goto out;
SSVAL(params,24,0); /* Padding. */
if (flags & 8) {
uint32 ea_size = estimate_ea_size(conn, fsp,
- fsp->fsp_name->base_name);
+ smb_fname);
SIVAL(params, 26, ea_size);
} else {
SIVAL(params, 26, 0);
if (case_sensitive) {
return strcmp(str,mask)==0;
} else {
- return StrCaseCmp(str,mask) == 0;
+ return strcasecmp_m(str,mask) == 0;
}
}
uint32_t len;
struct timespec mdate_ts, adate_ts, cdate_ts, create_date_ts;
time_t mdate = (time_t)0, adate = (time_t)0, create_date = (time_t)0;
- time_t c_date = (time_t)0;
char *nameptr;
char *last_entry_ptr;
bool was_8_3;
ZERO_STRUCT(create_date_ts);
ZERO_STRUCT(cdate_ts);
- if (!(mode & aDIR)) {
+ if (!(mode & FILE_ATTRIBUTE_DIRECTORY)) {
file_size = get_file_size_stat(&smb_fname->st);
}
allocation_size = SMB_VFS_GET_ALLOC_SIZE(conn, NULL, &smb_fname->st);
create_date = convert_timespec_to_time_t(create_date_ts);
mdate = convert_timespec_to_time_t(mdate_ts);
adate = convert_timespec_to_time_t(adate_ts);
- c_date = convert_timespec_to_time_t(cdate_ts);
/* align the record */
SMB_ASSERT(align >= 1);
SSVAL(p,20,mode);
{
unsigned int ea_size = estimate_ea_size(conn, NULL,
- smb_fname->base_name);
+ smb_fname);
SIVAL(p,22,ea_size); /* Extended attributes */
}
p += 27;
{
struct ea_list *file_list = NULL;
size_t ea_len = 0;
+ NTSTATUS status;
DEBUG(10,("smbd_marshall_dir_entry: SMB_FIND_EA_LIST\n"));
if (!name_list) {
SSVAL(p,20,mode);
p += 22; /* p now points to the EA area. */
- file_list = get_ea_list_from_file(ctx, conn, NULL,
- smb_fname->base_name,
- &ea_len);
+ status = get_ea_list_from_file(ctx, conn, NULL,
+ smb_fname,
+ &ea_len, &file_list);
+ if (!NT_STATUS_IS_OK(status)) {
+ file_list = NULL;
+ }
name_list = ea_list_union(name_list, file_list, &ea_len);
/* We need to determine if this entry will fit in the space available. */
q = p; p += 4; /* q is placeholder for name length. */
{
unsigned int ea_size = estimate_ea_size(conn, NULL,
- smb_fname->base_name);
+ smb_fname);
SIVAL(p,0,ea_size); /* Extended attributes */
p += 4;
}
q = p; p += 4; /* q is placeholder for name length. */
{
unsigned int ea_size = estimate_ea_size(conn, NULL,
- smb_fname->base_name);
+ smb_fname);
SIVAL(p,0,ea_size); /* Extended attributes */
p +=4;
}
q = p; p += 4; /* q is placeholder for name length. */
{
unsigned int ea_size = estimate_ea_size(conn, NULL,
- smb_fname->base_name);
+ smb_fname);
SIVAL(p,0,ea_size); /* Extended attributes */
p +=4;
}
q = p; p += 4; /* q is placeholder for name length */
{
unsigned int ea_size = estimate_ea_size(conn, NULL,
- smb_fname->base_name);
+ smb_fname);
SIVAL(p,0,ea_size); /* Extended attributes */
p +=4;
}
TALLOC_CTX *ctx = talloc_tos();
struct dptr_struct *dirptr = NULL;
struct smbd_server_connection *sconn = req->sconn;
+ uint32_t ucf_flags = (UCF_SAVE_LCOMP | UCF_ALWAYS_ALLOW_WCARD_LCOMP);
+ bool backup_priv = false;
if (total_params < 13) {
reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
close_after_first = (findfirst_flags & FLAG_TRANS2_FIND_CLOSE);
close_if_end = (findfirst_flags & FLAG_TRANS2_FIND_CLOSE_IF_END);
requires_resume_key = (findfirst_flags & FLAG_TRANS2_FIND_REQUIRE_RESUME);
+ backup_priv = ((findfirst_flags & FLAG_TRANS2_FIND_BACKUP_INTENT) &&
+ security_token_has_privilege(get_current_nttok(conn),
+ SEC_PRIV_BACKUP));
+
info_level = SVAL(params,6);
DEBUG(3,("call_trans2findfirst: dirtype = %x, maxentries = %d, close_after_first=%d, \
-close_if_end = %d requires_resume_key = %d level = 0x%x, max_data_bytes = %d\n",
+close_if_end = %d requires_resume_key = %d backup_priv = %d level = 0x%x, max_data_bytes = %d\n",
(unsigned int)dirtype, maxentries, close_after_first, close_if_end, requires_resume_key,
+ (int)backup_priv,
info_level, max_data_bytes));
if (!maxentries) {
reply_nterror(req, NT_STATUS_INVALID_LEVEL);
goto out;
}
+ ucf_flags |= UCF_UNIX_NAME_LOOKUP;
break;
default:
reply_nterror(req, NT_STATUS_INVALID_LEVEL);
goto out;
}
- ntstatus = filename_convert(ctx, conn,
+ if (backup_priv) {
+ become_root();
+ ntstatus = filename_convert_with_privilege(ctx,
+ conn,
+ req,
+ directory,
+ ucf_flags,
+ &mask_contains_wcard,
+ &smb_dname);
+ } else {
+ ntstatus = filename_convert(ctx, conn,
req->flags2 & FLAGS2_DFS_PATHNAMES,
directory,
- (UCF_SAVE_LCOMP |
- UCF_ALWAYS_ALLOW_WCARD_LCOMP),
+ ucf_flags,
&mask_contains_wcard,
&smb_dname);
+ }
+
if (!NT_STATUS_IS_OK(ntstatus)) {
if (NT_STATUS_EQUAL(ntstatus,NT_STATUS_PATH_NOT_COVERED)) {
reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
}
mask_contains_wcard = True;
}
- directory = talloc_strdup(talloc_tos(), "./");
+ } else {
+ *p = 0;
+ }
+
+ if (p == NULL || p == directory) {
+ /* Ensure we don't have a directory name of "". */
+ directory = talloc_strdup(talloc_tos(), ".");
if (!directory) {
reply_nterror(req, NT_STATUS_NO_MEMORY);
goto out;
}
- } else {
- *p = 0;
}
DEBUG(5,("dir=%s, mask = %s\n",directory, mask));
needed as lanman2 assumes these are being saved between calls */
ntstatus = dptr_create(conn,
+ req,
+ NULL, /* fsp */
directory,
False,
True,
goto out;
}
+ if (backup_priv) {
+ /* Remember this in case we have
+ to do a findnext. */
+ dptr_set_priv(dirptr);
+ }
+
dptr_num = dptr_dnum(dirptr);
DEBUG(4,("dptr_num is %d, wcard = %s, attr = %d\n", dptr_num, mask, dirtype));
a different TRANS2 call. */
DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n",
- directory,lp_dontdescend(SNUM(conn))));
- if (in_list(directory,lp_dontdescend(SNUM(conn)),conn->case_sensitive))
+ directory,lp_dontdescend(ctx, SNUM(conn))));
+ if (in_list(directory,lp_dontdescend(ctx, SNUM(conn)),conn->case_sensitive))
dont_descend = True;
p = pdata;
name_to_8_3(mask, mangled_name, True, conn->params);
}
out:
+
+ if (backup_priv) {
+ unbecome_root();
+ }
+
TALLOC_FREE(smb_dname);
return;
}
TALLOC_CTX *ctx = talloc_tos();
struct dptr_struct *dirptr;
struct smbd_server_connection *sconn = req->sconn;
+ bool backup_priv = false;
if (total_params < 13) {
reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
directory = dptr_path(sconn, dptr_num);
/* Get the wildcard mask from the dptr */
- if((p = dptr_wcard(sconn, dptr_num))== NULL) {
+ if((mask = dptr_wcard(sconn, dptr_num))== NULL) {
DEBUG(2,("dptr_num %d has no wildcard\n", dptr_num));
reply_nterror(req, STATUS_NO_MORE_FILES);
return;
}
- mask = p;
-
/* Get the attr mask from the dptr */
dirtype = dptr_attr(sconn, dptr_num);
- DEBUG(3,("dptr_num is %d, mask = %s, attr = %x, dirptr=(0x%lX,%ld)\n",
+ backup_priv = dptr_get_priv(dirptr);
+
+ DEBUG(3,("dptr_num is %d, mask = %s, attr = %x, dirptr=(0x%lX,%ld) "
+ "backup_priv = %d\n",
dptr_num, mask, dirtype,
(long)dirptr,
- dptr_TellDir(dirptr)));
+ dptr_TellDir(dirptr),
+ (int)backup_priv));
/* Initialize per TRANS2_FIND_NEXT operation data */
dptr_init_search_op(dirptr);
a different TRANS2 call. */
DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n",
- directory,lp_dontdescend(SNUM(conn))));
- if (in_list(directory,lp_dontdescend(SNUM(conn)),conn->case_sensitive))
+ directory,lp_dontdescend(ctx, SNUM(conn))));
+ if (in_list(directory,lp_dontdescend(ctx, SNUM(conn)),conn->case_sensitive))
dont_descend = True;
p = pdata;
space_remaining = max_data_bytes;
out_of_space = False;
+ if (backup_priv) {
+ become_root();
+ }
+
/*
* Seek to the correct position. We no longer use the resume key but
* depend on the last file name instead.
dptr_close(sconn, &dptr_num); /* This frees up the saved mask */
}
+ if (backup_priv) {
+ unbecome_root();
+ }
+
/* Set up the return parameter block */
SSVAL(params,0,numentries);
SSVAL(params,2,finished);
unsigned char *create_volume_objectid(connection_struct *conn, unsigned char objid[16])
{
- E_md4hash(lp_servicename(SNUM(conn)),objid);
+ E_md4hash(lp_servicename(talloc_tos(), SNUM(conn)),objid);
return objid;
}
{
char *pdata, *end_data;
int data_len = 0, len;
- const char *vname = volume_label(SNUM(conn));
+ const char *vname = volume_label(talloc_tos(), SNUM(conn));
int snum = SNUM(conn);
- char *fstype = lp_fstype(SNUM(conn));
+ char *fstype = lp_fstype(talloc_tos(), SNUM(conn));
uint32 additional_flags = 0;
struct smb_filename smb_fname_dot;
SMB_STRUCT_STAT st;
* Add volume serial number - hash of a combination of
* the called hostname and the service name.
*/
- SIVAL(pdata,0,str_checksum(lp_servicename(snum)) ^ (str_checksum(get_local_machine_name())<<16) );
+ SIVAL(pdata,0,str_checksum(lp_servicename(talloc_tos(), snum)) ^ (str_checksum(get_local_machine_name())<<16) );
/*
* Win2k3 and previous mess this up by sending a name length
* one byte short. I believe only older clients (OS/2 Win9x) use
* Add volume serial number - hash of a combination of
* the called hostname and the service name.
*/
- SIVAL(pdata,8,str_checksum(lp_servicename(snum)) ^
+ SIVAL(pdata,8,str_checksum(lp_servicename(talloc_tos(), snum)) ^
(str_checksum(get_local_machine_name())<<16));
/* Max label len is 32 characters. */
data_len = 18+len;
DEBUG(5,("smbd_do_qfsinfo : SMB_QUERY_FS_VOLUME_INFO namelen = %d, vol=%s serv=%s\n",
- (int)strlen(vname),vname, lp_servicename(snum)));
+ (int)strlen(vname),vname,
+ lp_servicename(talloc_tos(), snum)));
break;
case SMB_QUERY_FS_SIZE_INFO:
ZERO_STRUCT(quotas);
fsp.conn = conn;
- fsp.fnum = -1;
+ fsp.fnum = FNUM_FIELD_INVALID;
/* access check */
- if (conn->server_info->utok.uid != sec_initial_uid()) {
+ if (get_current_uid(conn) != 0) {
DEBUG(0,("set_user_quota: access_denied "
"service [%s] user [%s]\n",
- lp_servicename(SNUM(conn)),
- conn->server_info->unix_name));
+ lp_servicename(talloc_tos(), SNUM(conn)),
+ conn->session_info->unix_info->unix_name));
return NT_STATUS_ACCESS_DENIED;
}
if (vfs_get_ntquota(&fsp, SMB_USER_FS_QUOTA_TYPE, NULL, "as)!=0) {
- DEBUG(0,("vfs_get_ntquota() failed for service [%s]\n",lp_servicename(SNUM(conn))));
+ DEBUG(0,("vfs_get_ntquota() failed for service [%s]\n",lp_servicename(talloc_tos(), SNUM(conn))));
return map_nt_error_from_unix(errno);
}
data_len = 48;
DEBUG(10,("SMB_FS_QUOTA_INFORMATION: for service [%s]\n",
- lp_servicename(SNUM(conn))));
+ lp_servicename(talloc_tos(), SNUM(conn))));
/* Unknown1 24 NULL bytes*/
SBIG_UINT(pdata,0,(uint64_t)0);
}
switch (conn->encrypt_level) {
- case 0:
+ case SMB_SIGNING_OFF:
encrypt_caps = 0;
break;
- case 1:
- case Auto:
+ case SMB_SIGNING_IF_REQUIRED:
+ case SMB_SIGNING_DEFAULT:
encrypt_caps = CIFS_UNIX_TRANSPORT_ENCRYPTION_CAP;
break;
- case Required:
+ case SMB_SIGNING_REQUIRED:
encrypt_caps = CIFS_UNIX_TRANSPORT_ENCRYPTION_CAP|
CIFS_UNIX_TRANSPORT_ENCRYPTION_MANDATORY_CAP;
large_write = false;
return NT_STATUS_INVALID_LEVEL;
#endif /* EOPNOTSUPP */
} else {
- DEBUG(0,("vfs_statvfs() failed for service [%s]\n",lp_servicename(SNUM(conn))));
+ DEBUG(0,("vfs_statvfs() failed for service [%s]\n",lp_servicename(talloc_tos(), SNUM(conn))));
return NT_STATUS_DOS(ERRSRV, ERRerror);
}
break;
return NT_STATUS_BUFFER_TOO_SMALL;
}
- /* We ARE guest if global_sid_Builtin_Guests is
- * in our list of SIDs.
- */
- if (nt_token_check_sid(&global_sid_Builtin_Guests,
- conn->server_info->ptok)) {
+ if (security_session_user_level(conn->session_info, NULL) < SECURITY_USER) {
flags |= SMB_WHOAMI_GUEST;
}
- /* We are NOT guest if global_sid_Authenticated_Users
- * is in our list of SIDs.
- */
- if (nt_token_check_sid(&global_sid_Authenticated_Users,
- conn->server_info->ptok)) {
- flags &= ~SMB_WHOAMI_GUEST;
- }
-
/* NOTE: 8 bytes for UID/GID, irrespective of native
* platform size. This matches
* SMB_QUERY_FILE_UNIX_BASIC and friends.
+ 4 /* num_sids */
+ 4 /* SID bytes */
+ 4 /* pad/reserved */
- + (conn->server_info->utok.ngroups * 8)
+ + (conn->session_info->unix_token->ngroups * 8)
/* groups list */
- + (conn->server_info->ptok->num_sids *
+ + (conn->session_info->security_token->num_sids *
SID_MAX_SIZE)
/* SID list */;
SIVAL(pdata, 0, flags);
SIVAL(pdata, 4, SMB_WHOAMI_MASK);
SBIG_UINT(pdata, 8,
- (uint64_t)conn->server_info->utok.uid);
+ (uint64_t)conn->session_info->unix_token->uid);
SBIG_UINT(pdata, 16,
- (uint64_t)conn->server_info->utok.gid);
+ (uint64_t)conn->session_info->unix_token->gid);
if (data_len >= max_data_bytes) {
break;
}
- SIVAL(pdata, 24, conn->server_info->utok.ngroups);
- SIVAL(pdata, 28, conn->server_info->ptok->num_sids);
+ SIVAL(pdata, 24, conn->session_info->unix_token->ngroups);
+ SIVAL(pdata, 28, conn->session_info->security_token->num_sids);
/* We walk the SID list twice, but this call is fairly
* infrequent, and I don't expect that it's performance
* sensitive -- jpeach
*/
for (i = 0, sid_bytes = 0;
- i < conn->server_info->ptok->num_sids; ++i) {
+ i < conn->session_info->security_token->num_sids; ++i) {
sid_bytes += ndr_size_dom_sid(
- &conn->server_info->ptok->sids[i],
+ &conn->session_info->security_token->sids[i],
0);
}
data_len = 40;
/* GID list */
- for (i = 0; i < conn->server_info->utok.ngroups; ++i) {
+ for (i = 0; i < conn->session_info->unix_token->ngroups; ++i) {
SBIG_UINT(pdata, data_len,
- (uint64_t)conn->server_info->utok.groups[i]);
+ (uint64_t)conn->session_info->unix_token->groups[i]);
data_len += 8;
}
/* SID list */
for (i = 0;
- i < conn->server_info->ptok->num_sids; ++i) {
+ i < conn->session_info->security_token->num_sids; ++i) {
int sid_len = ndr_size_dom_sid(
- &conn->server_info->ptok->sids[i],
+ &conn->session_info->security_token->sids[i],
0);
sid_linearize(pdata + data_len, sid_len,
- &conn->server_info->ptok->sids[i]);
+ &conn->session_info->security_token->sids[i]);
data_len += sid_len;
}
* Thursby MAC extension... ONLY on NTFS filesystems
* once we do streams then we don't need this
*/
- if (strequal(lp_fstype(SNUM(conn)),"NTFS")) {
+ if (strequal(lp_fstype(talloc_tos(), SNUM(conn)),"NTFS")) {
data_len = 88;
SIVAL(pdata,84,0x100); /* Don't support mac... */
break;
DEBUG(0,("call_trans2qfsinfo: encryption required "
"and info level 0x%x sent.\n",
(unsigned int)info_level));
- exit_server_cleanly("encryption required "
- "on connection");
+ reply_nterror(req, NT_STATUS_ACCESS_DENIED);
return;
}
}
char **ppdata, int total_data,
unsigned int max_data_bytes)
{
+ struct smbd_server_connection *sconn = req->sconn;
char *pdata = *ppdata;
char *params = *pparams;
uint16 info_level;
- DEBUG(10,("call_trans2setfsinfo: for service [%s]\n",lp_servicename(SNUM(conn))));
+ DEBUG(10,("call_trans2setfsinfo: for service [%s]\n",
+ lp_servicename(talloc_tos(), SNUM(conn))));
/* */
if (total_params < 4) {
DEBUG(0,("call_trans2setfsinfo: encryption required "
"and info level 0x%x sent.\n",
(unsigned int)info_level));
- exit_server_cleanly("encryption required "
- "on connection");
+ reply_nterror(req, NT_STATUS_ACCESS_DENIED);
return;
}
}
switch(info_level) {
case SMB_SET_CIFS_UNIX_INFO:
- {
- uint16 client_unix_major;
- uint16 client_unix_minor;
- uint32 client_unix_cap_low;
- uint32 client_unix_cap_high;
-
- if (!lp_unix_extensions()) {
- reply_nterror(req,
- NT_STATUS_INVALID_LEVEL);
- return;
- }
+ if (!lp_unix_extensions()) {
+ DEBUG(2,("call_trans2setfsinfo: "
+ "SMB_SET_CIFS_UNIX_INFO is invalid with "
+ "unix extensions off\n"));
+ reply_nterror(req,
+ NT_STATUS_INVALID_LEVEL);
+ return;
+ }
- /* There should be 12 bytes of capabilities set. */
- if (total_data < 8) {
- reply_nterror(
- req,
- NT_STATUS_INVALID_PARAMETER);
- return;
- }
- client_unix_major = SVAL(pdata,0);
- client_unix_minor = SVAL(pdata,2);
- client_unix_cap_low = IVAL(pdata,4);
- client_unix_cap_high = IVAL(pdata,8);
- /* Just print these values for now. */
- DEBUG(10,("call_trans2setfsinfo: set unix info. major = %u, minor = %u \
-cap_low = 0x%x, cap_high = 0x%x\n",
- (unsigned int)client_unix_major,
- (unsigned int)client_unix_minor,
- (unsigned int)client_unix_cap_low,
- (unsigned int)client_unix_cap_high ));
-
- /* Here is where we must switch to posix pathname processing... */
- if (client_unix_cap_low & CIFS_UNIX_POSIX_PATHNAMES_CAP) {
- lp_set_posix_pathnames();
- mangle_change_to_posix();
- }
+ /* There should be 12 bytes of capabilities set. */
+ if (total_data < 12) {
+ reply_nterror(
+ req,
+ NT_STATUS_INVALID_PARAMETER);
+ return;
+ }
+ sconn->smb1.unix_info.client_major = SVAL(pdata,0);
+ sconn->smb1.unix_info.client_minor = SVAL(pdata,2);
+ sconn->smb1.unix_info.client_cap_low = IVAL(pdata,4);
+ sconn->smb1.unix_info.client_cap_high = IVAL(pdata,8);
+ /* Just print these values for now. */
+ DEBUG(10, ("call_trans2setfsinfo: set unix_info info. "
+ "major = %u, minor = %u cap_low = 0x%x, "
+ "cap_high = 0x%xn",
+ (unsigned int)sconn->
+ smb1.unix_info.client_major,
+ (unsigned int)sconn->
+ smb1.unix_info.client_minor,
+ (unsigned int)sconn->
+ smb1.unix_info.client_cap_low,
+ (unsigned int)sconn->
+ smb1.unix_info.client_cap_high));
+
+ /* Here is where we must switch to posix pathname processing... */
+ if (sconn->smb1.unix_info.client_cap_low & CIFS_UNIX_POSIX_PATHNAMES_CAP) {
+ lp_set_posix_pathnames();
+ mangle_change_to_posix();
+ }
- if ((client_unix_cap_low & CIFS_UNIX_FCNTL_LOCKS_CAP) &&
- !(client_unix_cap_low & CIFS_UNIX_POSIX_PATH_OPERATIONS_CAP)) {
- /* Client that knows how to do posix locks,
- * but not posix open/mkdir operations. Set a
- * default type for read/write checks. */
+ if ((sconn->smb1.unix_info.client_cap_low & CIFS_UNIX_FCNTL_LOCKS_CAP) &&
+ !(sconn->smb1.unix_info.client_cap_low & CIFS_UNIX_POSIX_PATH_OPERATIONS_CAP)) {
+ /* Client that knows how to do posix locks,
+ * but not posix open/mkdir operations. Set a
+ * default type for read/write checks. */
- lp_set_posix_default_cifsx_readwrite_locktype(POSIX_LOCK);
+ lp_set_posix_default_cifsx_readwrite_locktype(POSIX_LOCK);
- }
- break;
}
+ break;
case SMB_REQUEST_TRANSPORT_ENCRYPTION:
{
return;
}
- if (lp_smb_encrypt(SNUM(conn)) == false) {
+ if (lp_smb_encrypt(SNUM(conn)) == SMB_SIGNING_OFF) {
reply_nterror(
req,
NT_STATUS_NOT_SUPPORTED);
* encryption is now *on*. */
status = srv_encryption_start(conn);
if (!NT_STATUS_IS_OK(status)) {
- exit_server_cleanly(
- "Failure in setting "
- "up encrypted transport");
+ char *reason = talloc_asprintf(talloc_tos(),
+ "Failure in setting "
+ "up encrypted transport: %s",
+ nt_errstr(status));
+ exit_server_cleanly(reason);
}
}
return;
ZERO_STRUCT(quotas);
/* access check */
- if ((conn->server_info->utok.uid != sec_initial_uid())
- ||!CAN_WRITE(conn)) {
+ if ((get_current_uid(conn) != 0) || !CAN_WRITE(conn)) {
DEBUG(0,("set_user_quota: access_denied service [%s] user [%s]\n",
- lp_servicename(SNUM(conn)),
- conn->server_info->unix_name));
+ lp_servicename(talloc_tos(), SNUM(conn)),
+ conn->session_info->unix_info->unix_name));
reply_nterror(req, NT_STATUS_ACCESS_DENIED);
return;
}
/* unknown_1 24 NULL bytes in pdata*/
/* the soft quotas 8 bytes (uint64_t)*/
- quotas.softlim = (uint64_t)IVAL(pdata,24);
-#ifdef LARGE_SMB_OFF_T
- quotas.softlim |= (((uint64_t)IVAL(pdata,28)) << 32);
-#else /* LARGE_SMB_OFF_T */
- if ((IVAL(pdata,28) != 0)&&
- ((quotas.softlim != 0xFFFFFFFF)||
- (IVAL(pdata,28)!=0xFFFFFFFF))) {
- /* more than 32 bits? */
- reply_nterror(
- req,
- NT_STATUS_INVALID_PARAMETER);
- return;
- }
-#endif /* LARGE_SMB_OFF_T */
+ quotas.softlim = BVAL(pdata,24);
/* the hard quotas 8 bytes (uint64_t)*/
- quotas.hardlim = (uint64_t)IVAL(pdata,32);
-#ifdef LARGE_SMB_OFF_T
- quotas.hardlim |= (((uint64_t)IVAL(pdata,36)) << 32);
-#else /* LARGE_SMB_OFF_T */
- if ((IVAL(pdata,36) != 0)&&
- ((quotas.hardlim != 0xFFFFFFFF)||
- (IVAL(pdata,36)!=0xFFFFFFFF))) {
- /* more than 32 bits? */
- reply_nterror(
- req,
- NT_STATUS_INVALID_PARAMETER);
- return;
- }
-#endif /* LARGE_SMB_OFF_T */
+ quotas.hardlim = BVAL(pdata,32);
/* quota_flags 2 bytes **/
quotas.qflags = SVAL(pdata,40);
/* now set the quotas */
if (vfs_set_ntquota(fsp, SMB_USER_FS_QUOTA_TYPE, NULL, "as)!=0) {
- DEBUG(0,("vfs_set_ntquota() failed for service [%s]\n",lp_servicename(SNUM(conn))));
+ DEBUG(0,("vfs_set_ntquota() failed for service [%s]\n",lp_servicename(talloc_tos(), SNUM(conn))));
reply_nterror(req, map_nt_error_from_unix(errno));
return;
}
int entry_id = SMB_ACL_FIRST_ENTRY;
SMB_ACL_ENTRY_T entry;
- while ( posix_acl && (SMB_VFS_SYS_ACL_GET_ENTRY(conn, posix_acl, entry_id, &entry) == 1)) {
+ while ( posix_acl && (sys_acl_get_entry(posix_acl, entry_id, &entry) == 1)) {
/* get_next... */
if (entry_id == SMB_ACL_FIRST_ENTRY) {
entry_id = SMB_ACL_NEXT_ENTRY;
int entry_id = SMB_ACL_FIRST_ENTRY;
SMB_ACL_ENTRY_T entry;
- while ( posix_acl && (SMB_VFS_SYS_ACL_GET_ENTRY(conn, posix_acl, entry_id, &entry) == 1)) {
+ while ( posix_acl && (sys_acl_get_entry(posix_acl, entry_id, &entry) == 1)) {
SMB_ACL_TAG_T tagtype;
SMB_ACL_PERMSET_T permset;
unsigned char perms = 0;
entry_id = SMB_ACL_NEXT_ENTRY;
}
- if (SMB_VFS_SYS_ACL_GET_TAG_TYPE(conn, entry, &tagtype) == -1) {
+ if (sys_acl_get_tag_type(entry, &tagtype) == -1) {
DEBUG(0,("marshall_posix_acl: SMB_VFS_SYS_ACL_GET_TAG_TYPE failed.\n"));
return False;
}
- if (SMB_VFS_SYS_ACL_GET_PERMSET(conn, entry, &permset) == -1) {
+ if (sys_acl_get_permset(entry, &permset) == -1) {
DEBUG(0,("marshall_posix_acl: SMB_VFS_SYS_ACL_GET_PERMSET failed.\n"));
return False;
}
- perms |= (SMB_VFS_SYS_ACL_GET_PERM(conn, permset, SMB_ACL_READ) ? SMB_POSIX_ACL_READ : 0);
- perms |= (SMB_VFS_SYS_ACL_GET_PERM(conn, permset, SMB_ACL_WRITE) ? SMB_POSIX_ACL_WRITE : 0);
- perms |= (SMB_VFS_SYS_ACL_GET_PERM(conn, permset, SMB_ACL_EXECUTE) ? SMB_POSIX_ACL_EXECUTE : 0);
+ perms |= (sys_acl_get_perm(permset, SMB_ACL_READ) ? SMB_POSIX_ACL_READ : 0);
+ perms |= (sys_acl_get_perm(permset, SMB_ACL_WRITE) ? SMB_POSIX_ACL_WRITE : 0);
+ perms |= (sys_acl_get_perm(permset, SMB_ACL_EXECUTE) ? SMB_POSIX_ACL_EXECUTE : 0);
SCVAL(pdata,1,perms);
break;
case SMB_ACL_USER:
{
- uid_t *puid = (uid_t *)SMB_VFS_SYS_ACL_GET_QUALIFIER(conn, entry);
+ uid_t *puid = (uid_t *)sys_acl_get_qualifier(entry);
if (!puid) {
DEBUG(0,("marshall_posix_acl: SMB_VFS_SYS_ACL_GET_QUALIFIER failed.\n"));
return False;
}
own_grp = (unsigned int)*puid;
- SMB_VFS_SYS_ACL_FREE_QUALIFIER(conn, (void *)puid,tagtype);
SCVAL(pdata,0,SMB_POSIX_ACL_USER);
SIVAL(pdata,2,own_grp);
SIVAL(pdata,6,0);
break;
case SMB_ACL_GROUP:
{
- gid_t *pgid= (gid_t *)SMB_VFS_SYS_ACL_GET_QUALIFIER(conn, entry);
+ gid_t *pgid= (gid_t *)sys_acl_get_qualifier(entry);
if (!pgid) {
DEBUG(0,("marshall_posix_acl: SMB_VFS_SYS_ACL_GET_QUALIFIER failed.\n"));
return False;
}
own_grp = (unsigned int)*pgid;
- SMB_VFS_SYS_ACL_FREE_QUALIFIER(conn, (void *)pgid,tagtype);
SCVAL(pdata,0,SMB_POSIX_ACL_GROUP);
SIVAL(pdata,2,own_grp);
SIVAL(pdata,6,0);
const SMB_STRUCT_STAT *psbuf)
{
uint64_t file_index = get_FileIndex(conn, psbuf);
+ dev_t devno;
DEBUG(10,("store_file_unix_basic: SMB_QUERY_FILE_UNIX_BASIC\n"));
DEBUG(4,("store_file_unix_basic: st_mode=%o\n",(int)psbuf->st_ex_mode));
SIVAL(pdata,0,unix_filetype(psbuf->st_ex_mode));
pdata += 4;
- SIVAL(pdata,0,unix_dev_major(psbuf->st_ex_rdev)); /* Major device number if type is device */
+ if (S_ISBLK(psbuf->st_ex_mode) || S_ISCHR(psbuf->st_ex_mode)) {
+ devno = psbuf->st_ex_rdev;
+ } else {
+ devno = psbuf->st_ex_dev;
+ }
+
+ SIVAL(pdata,0,unix_dev_major(devno)); /* Major device number if type is device */
SIVAL(pdata,4,0);
pdata += 8;
- SIVAL(pdata,0,unix_dev_minor(psbuf->st_ex_rdev)); /* Minor device number if type is device */
+ SIVAL(pdata,0,unix_dev_minor(devno)); /* Minor device number if type is device */
SIVAL(pdata,4,0);
pdata += 8;
return NT_STATUS_INVALID_LEVEL;
}
- DEBUG(5,("smbd_do_qfilepathinfo: %s (fnum = %d) level=%d max_data=%u\n",
- smb_fname_str_dbg(smb_fname), fsp ? fsp->fnum : -1,
+ DEBUG(5,("smbd_do_qfilepathinfo: %s (%s) level=%d max_data=%u\n",
+ smb_fname_str_dbg(smb_fname),
+ fsp_fnum_dbg(fsp),
info_level, max_data_bytes));
mode = dos_mode(conn, smb_fname);
nlink = psbuf->st_ex_nlink;
- if (nlink && (mode&aDIR)) {
+ if (nlink && (mode&FILE_ATTRIBUTE_DIRECTORY)) {
nlink = 1;
}
}
}
- if (!(mode & aDIR)) {
+ if (!(mode & FILE_ATTRIBUTE_DIRECTORY)) {
file_size = get_file_size_stat(psbuf);
}
{
unsigned int ea_size =
estimate_ea_size(conn, fsp,
- smb_fname->base_name);
+ smb_fname);
DEBUG(10,("smbd_do_qfilepathinfo: SMB_INFO_QUERY_EA_SIZE\n"));
data_size = 26;
srv_put_dos_date2(pdata,0,create_time);
{
size_t total_ea_len = 0;
struct ea_list *ea_file_list = NULL;
-
DEBUG(10,("smbd_do_qfilepathinfo: SMB_INFO_QUERY_EAS_FROM_LIST\n"));
- ea_file_list =
+ status =
get_ea_list_from_file(mem_ctx, conn, fsp,
- smb_fname->base_name,
- &total_ea_len);
+ smb_fname,
+ &total_ea_len, &ea_file_list);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
ea_list = ea_list_union(ea_list, ea_file_list, &total_ea_len);
if (!ea_list || (total_ea_len > data_size)) {
{
/* We have data_size bytes to put EA's into. */
size_t total_ea_len = 0;
-
DEBUG(10,("smbd_do_qfilepathinfo: SMB_INFO_QUERY_ALL_EAS\n"));
- ea_list = get_ea_list_from_file(mem_ctx, conn, fsp,
- smb_fname->base_name,
- &total_ea_len);
+ status = get_ea_list_from_file(mem_ctx, conn, fsp,
+ smb_fname,
+ &total_ea_len, &ea_list);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
if (!ea_list || (total_ea_len > data_size)) {
data_size = 4;
SIVAL(pdata,0,4); /* EA List Length must be set to 4 if no EA's. */
/*TODO: add filtering and index handling */
- ea_file_list =
- get_ea_list_from_file(mem_ctx, conn, fsp,
- smb_fname->base_name,
- &total_ea_len);
+ status =
+ get_ea_list_from_file(mem_ctx, conn, fsp,
+ smb_fname,
+ &total_ea_len, &ea_file_list);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
if (!ea_file_list) {
return NT_STATUS_NO_EAS_ON_FILE;
}
SOFF_T(pdata,8,file_size);
SIVAL(pdata,16,nlink);
SCVAL(pdata,20,delete_pending?1:0);
- SCVAL(pdata,21,(mode&aDIR)?1:0);
+ SCVAL(pdata,21,(mode&FILE_ATTRIBUTE_DIRECTORY)?1:0);
SSVAL(pdata,22,0); /* Padding. */
break;
case SMB_QUERY_FILE_EA_INFO:
{
unsigned int ea_size =
- estimate_ea_size(conn, fsp, smb_fname->base_name);
+ estimate_ea_size(conn, fsp, smb_fname);
DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_EA_INFORMATION\n"));
data_size = 4;
SIVAL(pdata,0,ea_size);
{
int len;
unsigned int ea_size =
- estimate_ea_size(conn, fsp, smb_fname->base_name);
+ estimate_ea_size(conn, fsp, smb_fname);
DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_ALL_INFORMATION\n"));
put_long_date_timespec(conn->ts_res,pdata,create_time_ts);
put_long_date_timespec(conn->ts_res,pdata+8,atime_ts);
SOFF_T(pdata,8,file_size);
SIVAL(pdata,16,nlink);
SCVAL(pdata,20,delete_pending);
- SCVAL(pdata,21,(mode&aDIR)?1:0);
+ SCVAL(pdata,21,(mode&FILE_ATTRIBUTE_DIRECTORY)?1:0);
SSVAL(pdata,22,0);
pdata += 24;
SIVAL(pdata,0,ea_size);
{
int len;
unsigned int ea_size =
- estimate_ea_size(conn, fsp, smb_fname->base_name);
+ estimate_ea_size(conn, fsp, smb_fname);
DEBUG(10,("smbd_do_qfilepathinfo: SMB2_FILE_ALL_INFORMATION\n"));
put_long_date_timespec(conn->ts_res,pdata+0x00,create_time_ts);
put_long_date_timespec(conn->ts_res,pdata+0x08,atime_ts);
SBVAL(pdata, 0x30, file_size);
SIVAL(pdata, 0x38, nlink);
SCVAL(pdata, 0x3C, delete_pending);
- SCVAL(pdata, 0x3D, (mode&aDIR)?1:0);
+ SCVAL(pdata, 0x3D, (mode&FILE_ATTRIBUTE_DIRECTORY)?1:0);
SSVAL(pdata, 0x3E, 0); /* padding */
SBVAL(pdata, 0x40, file_index);
SIVAL(pdata, 0x48, ea_size);
*/
case SMB_QUERY_FILE_STREAM_INFO:
case SMB_FILE_STREAM_INFORMATION: {
- unsigned int num_streams;
- struct stream_struct *streams;
+ unsigned int num_streams = 0;
+ struct stream_struct *streams = NULL;
DEBUG(10,("smbd_do_qfilepathinfo: "
"SMB_FILE_STREAM_INFORMATION\n"));
return NT_STATUS_INVALID_PARAMETER;
}
- status = SMB_VFS_STREAMINFO(
- conn, fsp, smb_fname->base_name, talloc_tos(),
- &num_streams, &streams);
+ status = vfs_streaminfo(conn, fsp, smb_fname->base_name,
+ talloc_tos(), &num_streams, &streams);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(10, ("could not get stream info: %s\n",
case SMB_QUERY_FILE_UNIX_LINK:
{
int len;
- char *buffer = TALLOC_ARRAY(mem_ctx, char, PATH_MAX+1);
+ char *buffer = talloc_array(mem_ctx, char, PATH_MAX+1);
if (!buffer) {
return NT_STATUS_NO_MEMORY;
uint16 num_file_acls = 0;
uint16 num_def_acls = 0;
- if (fsp && !fsp->is_directory && (fsp->fh->fd != -1)) {
+ if (fsp && fsp->fh->fd != -1) {
file_acl = SMB_VFS_SYS_ACL_GET_FD(fsp);
} else {
file_acl =
(unsigned int)((num_file_acls + num_def_acls)*SMB_POSIX_ACL_ENTRY_SIZE +
SMB_POSIX_ACL_HEADER_SIZE) ));
if (file_acl) {
- SMB_VFS_SYS_ACL_FREE_ACL(conn, file_acl);
+ TALLOC_FREE(file_acl);
}
if (def_acl) {
- SMB_VFS_SYS_ACL_FREE_ACL(conn, def_acl);
+ TALLOC_FREE(def_acl);
}
return NT_STATUS_BUFFER_TOO_SMALL;
}
SSVAL(pdata,4,num_def_acls);
if (!marshall_posix_acl(conn, pdata + SMB_POSIX_ACL_HEADER_SIZE, psbuf, file_acl)) {
if (file_acl) {
- SMB_VFS_SYS_ACL_FREE_ACL(conn, file_acl);
+ TALLOC_FREE(file_acl);
}
if (def_acl) {
- SMB_VFS_SYS_ACL_FREE_ACL(conn, def_acl);
+ TALLOC_FREE(def_acl);
}
return NT_STATUS_INTERNAL_ERROR;
}
if (!marshall_posix_acl(conn, pdata + SMB_POSIX_ACL_HEADER_SIZE + (num_file_acls*SMB_POSIX_ACL_ENTRY_SIZE), psbuf, def_acl)) {
if (file_acl) {
- SMB_VFS_SYS_ACL_FREE_ACL(conn, file_acl);
+ TALLOC_FREE(file_acl);
}
if (def_acl) {
- SMB_VFS_SYS_ACL_FREE_ACL(conn, def_acl);
+ TALLOC_FREE(def_acl);
}
return NT_STATUS_INTERNAL_ERROR;
}
if (file_acl) {
- SMB_VFS_SYS_ACL_FREE_ACL(conn, file_acl);
+ TALLOC_FREE(file_acl);
}
if (def_acl) {
- SMB_VFS_SYS_ACL_FREE_ACL(conn, def_acl);
+ TALLOC_FREE(def_acl);
}
data_size = (num_file_acls + num_def_acls)*SMB_POSIX_ACL_ENTRY_SIZE + SMB_POSIX_ACL_HEADER_SIZE;
break;
enum brl_type lock_type;
/* We need an open file with a real fd for this. */
- if (!fsp || fsp->is_directory || fsp->fh->fd == -1) {
+ if (!fsp || fsp->fh->fd == -1) {
return NT_STATUS_INVALID_LEVEL;
}
/* We know this name is ok, it's already passed the checks. */
- } else if(fsp->is_directory || fsp->fh->fd == -1) {
+ } else if(fsp->fh->fd == -1) {
/*
* This is actually a QFILEINFO on a directory
* handle (returned from an NT SMB). NT5.0 seems
}
fileid = vfs_file_id_from_sbuf(conn, &smb_fname->st);
- get_file_infos(fileid, &delete_pending, &write_time_ts);
+ get_file_infos(fileid, fsp->name_hash, &delete_pending, &write_time_ts);
} else {
/*
* Original code - this is an open file.
*/
- if (!check_fsp(conn, req, fsp)) {
- return;
- }
-
if (SMB_VFS_FSTAT(fsp, &smb_fname->st) != 0) {
- DEBUG(3, ("fstat of fnum %d failed (%s)\n",
- fsp->fnum, strerror(errno)));
+ DEBUG(3, ("fstat of %s failed (%s)\n",
+ fsp_fnum_dbg(fsp), strerror(errno)));
reply_nterror(req,
map_nt_error_from_unix(errno));
return;
}
fileid = vfs_file_id_from_sbuf(conn, &smb_fname->st);
- get_file_infos(fileid, &delete_pending, &write_time_ts);
+ get_file_infos(fileid, fsp->name_hash, &delete_pending, &write_time_ts);
}
} else {
+ uint32_t name_hash;
char *fname = NULL;
+ uint32_t ucf_flags = 0;
/* qpathinfo */
if (total_params < 7) {
DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QPATHINFO: level = %d\n", info_level));
- if (INFO_LEVEL_IS_UNIX(info_level) && !lp_unix_extensions()) {
- reply_nterror(req, NT_STATUS_INVALID_LEVEL);
- return;
+ if (INFO_LEVEL_IS_UNIX(info_level)) {
+ if (!lp_unix_extensions()) {
+ reply_nterror(req, NT_STATUS_INVALID_LEVEL);
+ return;
+ }
+ if (info_level == SMB_QUERY_FILE_UNIX_BASIC ||
+ info_level == SMB_QUERY_FILE_UNIX_INFO2 ||
+ info_level == SMB_QUERY_FILE_UNIX_LINK) {
+ ucf_flags |= UCF_UNIX_NAME_LOOKUP;
+ }
}
srvstr_get_path(req, params, req->flags2, &fname, ¶ms[6],
conn,
req->flags2 & FLAGS2_DFS_PATHNAMES,
fname,
- 0,
+ ucf_flags,
NULL,
&smb_fname);
if (!NT_STATUS_IS_OK(status)) {
}
}
+ status = file_name_hash(conn,
+ smb_fname_str_dbg(smb_fname_base),
+ &name_hash);
+ if (!NT_STATUS_IS_OK(status)) {
+ TALLOC_FREE(smb_fname_base);
+ reply_nterror(req, status);
+ return;
+ }
+
fileid = vfs_file_id_from_sbuf(conn,
&smb_fname_base->st);
TALLOC_FREE(smb_fname_base);
- get_file_infos(fileid, &delete_pending, NULL);
+ get_file_infos(fileid, name_hash, &delete_pending, NULL);
if (delete_pending) {
reply_nterror(req, NT_STATUS_DELETE_PENDING);
return;
}
}
+ status = file_name_hash(conn,
+ smb_fname_str_dbg(smb_fname),
+ &name_hash);
+ if (!NT_STATUS_IS_OK(status)) {
+ reply_nterror(req, status);
+ return;
+ }
+
fileid = vfs_file_id_from_sbuf(conn, &smb_fname->st);
- get_file_infos(fileid, &delete_pending, &write_time_ts);
+ get_file_infos(fileid, name_hash, &delete_pending, &write_time_ts);
if (delete_pending) {
reply_nterror(req, NT_STATUS_DELETE_PENDING);
return;
}
}
- DEBUG(3,("call_trans2qfilepathinfo %s (fnum = %d) level=%d call=%d "
+ DEBUG(3,("call_trans2qfilepathinfo %s (%s) level=%d call=%d "
"total_data=%d\n", smb_fname_str_dbg(smb_fname),
- fsp ? fsp->fnum : -1, info_level,tran_call,total_data));
+ fsp_fnum_dbg(fsp),
+ info_level,tran_call,total_data));
/* Pull out any data sent here before we realloc. */
switch (info_level) {
}
/* Copy the lock range data. */
- lock_data = (char *)TALLOC_MEMDUP(
+ lock_data = (char *)talloc_memdup(
req, pdata, total_data);
if (!lock_data) {
reply_nterror(req, NT_STATUS_NO_MEMORY);
/****************************************************************************
Deal with setting the time from any of the setfilepathinfo functions.
+ NOTE !!!! The check for FILE_WRITE_ATTRIBUTES access must be done *before*
+ calling this function.
****************************************************************************/
NTSTATUS smb_set_file_time(connection_struct *conn,
/****************************************************************************
Deal with setting the dosmode from any of the setfilepathinfo functions.
+ NB. The check for FILE_WRITE_ATTRIBUTES access on this path must have been
+ done before calling this function.
****************************************************************************/
static NTSTATUS smb_set_file_dosmode(connection_struct *conn,
if (dosmode) {
if (S_ISDIR(smb_fname_base->st.st_ex_mode)) {
- dosmode |= aDIR;
+ dosmode |= FILE_ATTRIBUTE_DIRECTORY;
} else {
- dosmode &= ~aDIR;
+ dosmode &= ~FILE_ATTRIBUTE_DIRECTORY;
}
}
files_struct *fsp,
const struct smb_filename *smb_fname,
const SMB_STRUCT_STAT *psbuf,
- SMB_OFF_T size,
+ off_t size,
bool fail_after_createfile)
{
NTSTATUS status = NT_STATUS_OK;
if (fsp && fsp->fh->fd != -1) {
/* Handle based call. */
+ if (!(fsp->access_mask & FILE_WRITE_DATA)) {
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
if (vfs_set_filelen(fsp, size) == -1) {
return map_nt_error_from_unix(errno);
}
if (!ea_list) {
return NT_STATUS_INVALID_PARAMETER;
}
+
status = set_ea(conn, fsp, smb_fname, ea_list);
return status;
if (!ea_list) {
return NT_STATUS_INVALID_PARAMETER;
}
+
status = set_ea(conn, fsp, fsp->fsp_name, ea_list);
DEBUG(10, ("smb_set_file_full_ea_info on file %s returned %s\n",
/* The set is across all open files on this dev/inode pair. */
if (!set_delete_on_close(fsp, delete_on_close,
- &conn->server_info->utok)) {
+ conn->session_info->security_token,
+ conn->session_info->unix_token)) {
return NT_STATUS_ACCESS_DENIED;
}
return NT_STATUS_OK;
}
position_information = (uint64_t)IVAL(pdata,0);
-#ifdef LARGE_SMB_OFF_T
position_information |= (((uint64_t)IVAL(pdata,4)) << 32);
-#else /* LARGE_SMB_OFF_T */
- if (IVAL(pdata,4) != 0) {
- /* more than 32 bits? */
- return NT_STATUS_INVALID_PARAMETER;
- }
-#endif /* LARGE_SMB_OFF_T */
DEBUG(10,("smb_file_position_information: Set file position "
"information for file %s to %.0f\n", fsp_str_dbg(fsp),
}
DEBUG(10,("smb2_file_rename_information: "
- "SMB_FILE_RENAME_INFORMATION (fnum %d) %s -> %s\n",
- fsp->fnum, fsp_str_dbg(fsp),
+ "SMB_FILE_RENAME_INFORMATION (%s) %s -> %s\n",
+ fsp_fnum_dbg(fsp), fsp_str_dbg(fsp),
smb_fname_str_dbg(smb_fname_dst)));
- status = rename_internals_fsp(conn, fsp, smb_fname_dst, 0,
- overwrite);
+ status = rename_internals_fsp(conn, fsp, smb_fname_dst,
+ (FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM),
+ overwrite);
out:
TALLOC_FREE(smb_fname_dst);
}
DEBUG(10,("smb_file_link_information: "
- "SMB_FILE_LINK_INFORMATION (fnum %d) %s -> %s\n",
- fsp->fnum, fsp_str_dbg(fsp),
+ "SMB_FILE_LINK_INFORMATION (%s) %s -> %s\n",
+ fsp_fnum_dbg(fsp), fsp_str_dbg(fsp),
smb_fname_str_dbg(smb_fname_dst)));
status = hardlink_internals(ctx,
conn,
req->flags2 & FLAGS2_DFS_PATHNAMES,
newname,
true,
+ !conn->sconn->using_smb2,
&newname,
&dest_has_wcard);
if (!NT_STATUS_IS_OK(status)) {
if (p) {
p[1] = '\0';
} else {
- base_name = talloc_strdup(ctx, "./");
+ base_name = talloc_strdup(ctx, "");
if (!base_name) {
return NT_STATUS_NO_MEMORY;
}
if (fsp) {
DEBUG(10,("smb_file_rename_information: "
- "SMB_FILE_RENAME_INFORMATION (fnum %d) %s -> %s\n",
- fsp->fnum, fsp_str_dbg(fsp),
+ "SMB_FILE_RENAME_INFORMATION (%s) %s -> %s\n",
+ fsp_fnum_dbg(fsp), fsp_str_dbg(fsp),
smb_fname_str_dbg(smb_fname_dst)));
status = rename_internals_fsp(conn, fsp, smb_fname_dst, 0,
overwrite);
return NT_STATUS_INVALID_PARAMETER;
}
+ status = check_access(conn, fsp, smb_fname, FILE_WRITE_ATTRIBUTES);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
/* Set the attributes */
dosmode = IVAL(pdata,32);
status = smb_set_file_dosmode(conn, smb_fname, dosmode);
files_struct *fsp,
const struct smb_filename *smb_fname)
{
+ NTSTATUS status;
struct smb_file_time ft;
ZERO_STRUCT(ft);
DEBUG(10,("smb_set_info_standard: file %s\n",
smb_fname_str_dbg(smb_fname)));
+ status = check_access(conn, fsp, smb_fname, FILE_WRITE_ATTRIBUTES);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
return smb_set_file_time(conn,
fsp,
smb_fname,
}
allocation_size = (uint64_t)IVAL(pdata,0);
-#ifdef LARGE_SMB_OFF_T
allocation_size |= (((uint64_t)IVAL(pdata,4)) << 32);
-#else /* LARGE_SMB_OFF_T */
- if (IVAL(pdata,4) != 0) {
- /* more than 32 bits? */
- return NT_STATUS_INVALID_PARAMETER;
- }
-#endif /* LARGE_SMB_OFF_T */
-
DEBUG(10,("smb_set_file_allocation_info: Set file allocation info for "
"file %s to %.0f\n", smb_fname_str_dbg(smb_fname),
(double)allocation_size));
if (fsp && fsp->fh->fd != -1) {
/* Open file handle. */
+ if (!(fsp->access_mask & FILE_WRITE_DATA)) {
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
/* Only change if needed. */
if (allocation_size != get_file_size_stat(&smb_fname->st)) {
if (vfs_allocate_file_space(fsp, allocation_size) == -1) {
const struct smb_filename *smb_fname,
bool fail_after_createfile)
{
- SMB_OFF_T size;
+ off_t size;
if (total_data < 8) {
return NT_STATUS_INVALID_PARAMETER;
}
size = IVAL(pdata,0);
-#ifdef LARGE_SMB_OFF_T
- size |= (((SMB_OFF_T)IVAL(pdata,4)) << 32);
-#else /* LARGE_SMB_OFF_T */
- if (IVAL(pdata,4) != 0) {
- /* more than 32 bits? */
- return NT_STATUS_INVALID_PARAMETER;
- }
-#endif /* LARGE_SMB_OFF_T */
+ size |= (((off_t)IVAL(pdata,4)) << 32);
DEBUG(10,("smb_set_file_end_of_file_info: Set end of file info for "
"file %s to %.0f\n", smb_fname_str_dbg(smb_fname),
(double)size));
struct smb_file_time ft;
uint32 raw_unixmode;
mode_t unixmode;
- SMB_OFF_T size = 0;
+ off_t size = 0;
uid_t set_owner = (uid_t)SMB_UID_NO_CHANGE;
gid_t set_grp = (uid_t)SMB_GID_NO_CHANGE;
NTSTATUS status = NT_STATUS_OK;
if(IVAL(pdata, 0) != SMB_SIZE_NO_CHANGE_LO &&
IVAL(pdata, 4) != SMB_SIZE_NO_CHANGE_HI) {
size=IVAL(pdata,0); /* first 8 Bytes are size */
-#ifdef LARGE_SMB_OFF_T
- size |= (((SMB_OFF_T)IVAL(pdata,4)) << 32);
-#else /* LARGE_SMB_OFF_T */
- if (IVAL(pdata,4) != 0) {
- /* more than 32 bits? */
- return NT_STATUS_INVALID_PARAMETER;
- }
-#endif /* LARGE_SMB_OFF_T */
+ size |= (((off_t)IVAL(pdata,4)) << 32);
}
ft.atime = interpret_long_date(pdata+24); /* access_time */
Open/Create a file with POSIX semantics.
****************************************************************************/
+#define SMB_O_RDONLY_MAPPING (FILE_READ_DATA|FILE_READ_ATTRIBUTES|FILE_READ_EA)
+#define SMB_O_WRONLY_MAPPING (FILE_WRITE_DATA|FILE_WRITE_ATTRIBUTES|FILE_WRITE_EA)
+
static NTSTATUS smb_posix_open(connection_struct *conn,
struct smb_request *req,
char **ppdata,
uint32 mod_unixmode = 0;
uint32 create_disp = 0;
uint32 access_mask = 0;
- uint32 create_options = 0;
+ uint32 create_options = FILE_NON_DIRECTORY_FILE;
NTSTATUS status = NT_STATUS_OK;
mode_t unixmode = (mode_t)0;
files_struct *fsp = NULL;
switch (wire_open_mode & SMB_ACCMODE) {
case SMB_O_RDONLY:
- access_mask = FILE_READ_DATA;
+ access_mask = SMB_O_RDONLY_MAPPING;
break;
case SMB_O_WRONLY:
- access_mask = FILE_WRITE_DATA;
+ access_mask = SMB_O_WRONLY_MAPPING;
break;
case SMB_O_RDWR:
- access_mask = FILE_READ_DATA|FILE_WRITE_DATA;
+ access_mask = (SMB_O_RDONLY_MAPPING|
+ SMB_O_WRONLY_MAPPING);
break;
default:
DEBUG(5,("smb_posix_open: invalid open mode 0x%x\n",
wire_open_mode &= ~SMB_ACCMODE;
- if((wire_open_mode & (SMB_O_CREAT | SMB_O_EXCL)) == (SMB_O_CREAT | SMB_O_EXCL)) {
- create_disp = FILE_CREATE;
- } else if((wire_open_mode & (SMB_O_CREAT | SMB_O_TRUNC)) == (SMB_O_CREAT | SMB_O_TRUNC)) {
- create_disp = FILE_OVERWRITE_IF;
- } else if((wire_open_mode & SMB_O_CREAT) == SMB_O_CREAT) {
- create_disp = FILE_OPEN_IF;
- } else if ((wire_open_mode & (SMB_O_CREAT | SMB_O_EXCL | SMB_O_TRUNC)) == 0) {
- create_disp = FILE_OPEN;
- } else {
- DEBUG(5,("smb_posix_open: invalid create mode 0x%x\n",
- (unsigned int)wire_open_mode ));
- return NT_STATUS_INVALID_PARAMETER;
+ /* First take care of O_CREAT|O_EXCL interactions. */
+ switch (wire_open_mode & (SMB_O_CREAT | SMB_O_EXCL)) {
+ case (SMB_O_CREAT | SMB_O_EXCL):
+ /* File exists fail. File not exist create. */
+ create_disp = FILE_CREATE;
+ break;
+ case SMB_O_CREAT:
+ /* File exists open. File not exist create. */
+ create_disp = FILE_OPEN_IF;
+ break;
+ case 0:
+ /* File exists open. File not exist fail. */
+ create_disp = FILE_OPEN;
+ break;
+ case SMB_O_EXCL:
+ /* O_EXCL on its own without O_CREAT is undefined. */
+ default:
+ DEBUG(5,("smb_posix_open: invalid create mode 0x%x\n",
+ (unsigned int)wire_open_mode ));
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+
+ /* Next factor in the effects of O_TRUNC. */
+ wire_open_mode &= ~(SMB_O_CREAT | SMB_O_EXCL);
+
+ if (wire_open_mode & SMB_O_TRUNC) {
+ switch (create_disp) {
+ case FILE_CREATE:
+ /* (SMB_O_CREAT | SMB_O_EXCL | O_TRUNC) */
+ /* Leave create_disp alone as
+ (O_CREAT|O_EXCL|O_TRUNC) == (O_CREAT|O_EXCL)
+ */
+ /* File exists fail. File not exist create. */
+ break;
+ case FILE_OPEN_IF:
+ /* SMB_O_CREAT | SMB_O_TRUNC */
+ /* File exists overwrite. File not exist create. */
+ create_disp = FILE_OVERWRITE_IF;
+ break;
+ case FILE_OPEN:
+ /* SMB_O_TRUNC */
+ /* File exists overwrite. File not exist fail. */
+ create_disp = FILE_OVERWRITE;
+ break;
+ default:
+ /* Cannot get here. */
+ smb_panic("smb_posix_open: logic error");
+ return NT_STATUS_INVALID_PARAMETER;
+ }
}
raw_unixmode = IVAL(pdata,8);
mod_unixmode |= FILE_FLAG_NO_BUFFERING;
}
+ if ((wire_open_mode & SMB_O_DIRECTORY) ||
+ VALID_STAT_OF_DIR(smb_fname->st)) {
+ if (access_mask != SMB_O_RDONLY_MAPPING) {
+ return NT_STATUS_FILE_IS_A_DIRECTORY;
+ }
+ create_options &= ~FILE_NON_DIRECTORY_FILE;
+ create_options |= FILE_DIRECTORY_FILE;
+ }
+
DEBUG(10,("smb_posix_open: file %s, smb_posix_flags = %u, mode 0%o\n",
smb_fname_str_dbg(smb_fname),
(unsigned int)wire_open_mode,
(FILE_SHARE_READ | FILE_SHARE_WRITE | /* share_access */
FILE_SHARE_DELETE),
create_disp, /* create_disposition*/
- FILE_NON_DIRECTORY_FILE, /* create_options */
+ create_options, /* create_options */
mod_unixmode, /* file_attributes */
oplock_request, /* oplock_request */
0, /* allocation_size */
* non-POSIX opens return SHARING_VIOLATION.
*/
- lck = get_share_mode_lock(talloc_tos(), fsp->file_id, NULL, NULL,
- NULL);
+ lck = get_existing_share_mode_lock(talloc_tos(), fsp->file_id);
if (lck == NULL) {
DEBUG(0, ("smb_posix_unlink: Could not get share mode "
"lock for file %s\n", fsp_str_dbg(fsp)));
* don't delete. If all opens are POSIX delete we can set the delete
* on close disposition.
*/
- for (i=0; i<lck->num_share_modes; i++) {
- struct share_mode_entry *e = &lck->share_modes[i];
+ for (i=0; i<lck->data->num_share_modes; i++) {
+ struct share_mode_entry *e = &lck->data->share_modes[i];
if (is_valid_share_mode_entry(e)) {
if (e->flags & SHARE_MODE_FLAG_POSIX_OPEN) {
continue;
}
+ if (share_mode_stale_pid(lck->data, i)) {
+ continue;
+ }
/* Fail with sharing violation. */
close_file(req, fsp, NORMAL_CLOSE);
TALLOC_FREE(lck);
}
}
- DEBUG(3,("smbd_do_setfilepathinfo: %s (fnum %d) info_level=%d "
+ DEBUG(3,("smbd_do_setfilepathinfo: %s (%s) info_level=%d "
"totdata=%d\n", smb_fname_str_dbg(smb_fname),
- fsp ? fsp->fnum : -1, info_level, total_data));
+ fsp_fnum_dbg(fsp),
+ info_level, total_data));
switch (info_level) {
return;
}
- if(fsp->is_directory || fsp->fh->fd == -1) {
+ if(fsp->fh->fd == -1) {
/*
* This is actually a SETFILEINFO on a directory
* handle (returned from an NT SMB). NT5.0 seems
/*
* Original code - this is an open file.
*/
- if (!check_fsp(conn, req, fsp)) {
- return;
- }
-
if (SMB_VFS_FSTAT(fsp, &smb_fname->st) != 0) {
DEBUG(3,("call_trans2setfilepathinfo: fstat "
- "of fnum %d failed (%s)\n", fsp->fnum,
+ "of %s failed (%s)\n", fsp_fnum_dbg(fsp),
strerror(errno)));
reply_nterror(req, map_nt_error_from_unix(errno));
return;
}
} else {
char *fname = NULL;
+ uint32_t ucf_flags = 0;
/* set path info */
if (total_params < 7) {
return;
}
+ if (info_level == SMB_SET_FILE_UNIX_BASIC ||
+ info_level == SMB_SET_FILE_UNIX_INFO2 ||
+ info_level == SMB_FILE_RENAME_INFORMATION ||
+ info_level == SMB_POSIX_PATH_UNLINK) {
+ ucf_flags |= UCF_UNIX_NAME_LOOKUP;
+ }
+
status = filename_convert(req, conn,
req->flags2 & FLAGS2_DFS_PATHNAMES,
fname,
- 0,
+ ucf_flags,
NULL,
&smb_fname);
if (!NT_STATUS_IS_OK(status)) {
}
}
- DEBUG(3,("call_trans2setfilepathinfo(%d) %s (fnum %d) info_level=%d "
+ DEBUG(3,("call_trans2setfilepathinfo(%d) %s (%s) info_level=%d "
"totdata=%d\n", tran_call, smb_fname_str_dbg(smb_fname),
- fsp ? fsp->fnum : -1, info_level,total_data));
+ fsp_fnum_dbg(fsp),
+ info_level,total_data));
/* Realloc the parameter size */
*pparams = (char *)SMB_REALLOC(*pparams,2);
ppdata, total_data,
&data_return_size);
if (!NT_STATUS_IS_OK(status)) {
- if (open_was_deferred(req->mid)) {
+ if (open_was_deferred(req->sconn, req->mid)) {
/* We have re-scheduled this call. */
return;
}
return;
}
- SSVAL(req->inbuf, smb_flg2,
+ SSVAL((discard_const_p(uint8_t, req->inbuf)), smb_flg2,
SVAL(req->inbuf,smb_flg2) | FLAGS2_DFS_PATHNAMES);
send_trans2_replies(conn, req,0,0,*ppdata,reply_size, max_data_bytes);
CAN ACCEPT THIS IN UNICODE. JRA. */
/* Job number */
- if (fsp->print_file) {
- SSVAL(pdata, 0, fsp->print_file->rap_jobid);
- } else {
- SSVAL(pdata, 0, 0);
- }
+ SSVAL(pdata, 0, print_spool_rap_jobid(fsp->print_file));
+
srvstr_push(pdata, req->flags2, pdata + 2,
- global_myname(), 15,
+ lp_netbios_name(), 15,
STR_ASCII|STR_TERMINATE); /* Our NetBIOS name */
srvstr_push(pdata, req->flags2, pdata+18,
- lp_servicename(SNUM(conn)), 13,
+ lp_servicename(talloc_tos(), SNUM(conn)), 13,
STR_ASCII|STR_TERMINATE); /* Service name */
send_trans2_replies(conn, req, *pparams, 0, *ppdata, 32,
max_data_bytes);
{
if (get_Protocol() >= PROTOCOL_NT1) {
req->flags2 |= 0x40; /* IS_LONG_NAME */
- SSVAL(req->inbuf,smb_flg2,req->flags2);
+ SSVAL((discard_const_p(uint8_t, req->inbuf)),smb_flg2,req->flags2);
}
- if (conn->encrypt_level == Required && !req->encrypted) {
+ if (ENCRYPTION_REQUIRED(conn) && !req->encrypted) {
if (state->call != TRANSACT2_QFSINFO &&
- state->call != TRANSACT2_SETFSINFO) {
+ state->call != TRANSACT2_SETFSINFO) {
DEBUG(0,("handle_trans2: encryption required "
"with call 0x%x\n",
(unsigned int)state->call));
}
}
- if ((state = TALLOC_P(conn, struct trans_state)) == NULL) {
+ if ((state = talloc(conn, struct trans_state)) == NULL) {
DEBUG(0, ("talloc failed\n"));
reply_nterror(req, NT_STATUS_NO_MEMORY);
END_PROFILE(SMBtrans2);
START_PROFILE(SMBtranss2);
- show_msg((char *)req->inbuf);
+ show_msg((const char *)req->inbuf);
+
+ /* Windows clients expect all replies to
+ a transact secondary (SMBtranss2 0x33)
+ to have a command code of transact
+ (SMBtrans2 0x32). See bug #8989
+ and also [MS-CIFS] section 2.2.4.47.2
+ for details.
+ */
+ req->cmd = SMBtrans2;
if (req->wct < 8) {
reply_nterror(req, NT_STATUS_INVALID_PARAMETER);