#include "trans2.h"
#include "auth.h"
#include "smbprofile.h"
+#include "rpc_server/srv_pipe_hnd.h"
#define DIR_ENTRY_SAFETY_MARGIN 4096
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);
|| 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;
}
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;
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;
}
}
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;
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;
}
if (case_sensitive) {
return strcmp(str,mask)==0;
} else {
- return StrCaseCmp(str,mask) == 0;
+ return strcasecmp_m(str,mask) == 0;
}
}
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);
if (total_params < 13) {
reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
reply_nterror(req, NT_STATUS_INVALID_LEVEL);
goto out;
}
+ ucf_flags |= UCF_UNIX_NAME_LOOKUP;
break;
default:
reply_nterror(req, NT_STATUS_INVALID_LEVEL);
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)) {
DEBUG(0,("set_user_quota: access_denied "
"service [%s] user [%s]\n",
lp_servicename(SNUM(conn)),
- conn->session_info->unix_name));
+ conn->session_info->unix_info->unix_name));
return NT_STATUS_ACCESS_DENIED;
}
+ 4 /* num_sids */
+ 4 /* SID bytes */
+ 4 /* pad/reserved */
- + (conn->session_info->utok.ngroups * 8)
+ + (conn->session_info->unix_token->ngroups * 8)
/* groups list */
+ (conn->session_info->security_token->num_sids *
SID_MAX_SIZE)
SIVAL(pdata, 0, flags);
SIVAL(pdata, 4, SMB_WHOAMI_MASK);
SBIG_UINT(pdata, 8,
- (uint64_t)conn->session_info->utok.uid);
+ (uint64_t)conn->session_info->unix_token->uid);
SBIG_UINT(pdata, 16,
- (uint64_t)conn->session_info->utok.gid);
+ (uint64_t)conn->session_info->unix_token->gid);
if (data_len >= max_data_bytes) {
break;
}
- SIVAL(pdata, 24, conn->session_info->utok.ngroups);
+ 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
data_len = 40;
/* GID list */
- for (i = 0; i < conn->session_info->utok.ngroups; ++i) {
+ for (i = 0; i < conn->session_info->unix_token->ngroups; ++i) {
SBIG_UINT(pdata, data_len,
- (uint64_t)conn->session_info->utok.groups[i]);
+ (uint64_t)conn->session_info->unix_token->groups[i]);
data_len += 8;
}
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;
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()) {
+ 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 < 8) {
+ 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:
{
* 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;
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->session_info->unix_name));
+ conn->session_info->unix_info->unix_name));
reply_nterror(req, NT_STATUS_ACCESS_DENIED);
return;
}
*/
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;
} 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)) {
}
/* 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);
return NT_STATUS_INVALID_PARAMETER;
}
- if (fsp && !(fsp->access_mask & FILE_WRITE_EA)) {
+ if (!(fsp->access_mask & FILE_WRITE_EA)) {
return NT_STATUS_ACCESS_DENIED;
}
/* The set is across all open files on this dev/inode pair. */
if (!set_delete_on_close(fsp, delete_on_close,
- &conn->session_info->utok)) {
+ conn->session_info->unix_token)) {
return NT_STATUS_ACCESS_DENIED;
}
return NT_STATUS_OK;
"SMB_FILE_RENAME_INFORMATION (fnum %d) %s -> %s\n",
fsp->fnum, 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);
return NT_STATUS_INVALID_PARAMETER;
}
- if (fsp && !(fsp->access_mask & FILE_WRITE_ATTRIBUTES)) {
- return NT_STATUS_ACCESS_DENIED;
- }
-
/* create time */
ft.create_time = convert_time_t_to_timespec(srv_make_unix_date2(pdata));
/* access time */
allocation_size = smb_roundup(conn, allocation_size);
}
- if (fsp && !(fsp->access_mask & FILE_WRITE_DATA)) {
- return NT_STATUS_ACCESS_DENIED;
- }
-
DEBUG(10,("smb_set_file_allocation_info: file %s : setting new "
"allocation size 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) {
"file %s to %.0f\n", smb_fname_str_dbg(smb_fname),
(double)size));
- if (fsp && !(fsp->access_mask & FILE_WRITE_DATA)) {
- return NT_STATUS_ACCESS_DENIED;
- }
-
return smb_set_file_size(conn, req,
fsp,
smb_fname,
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,
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",
if (wire_open_mode & SMB_O_SYNC) {
create_options |= FILE_WRITE_THROUGH;
}
+ if (wire_open_mode & SMB_O_APPEND) {
+ access_mask |= FILE_APPEND_DATA;
+ }
+ if (wire_open_mode & SMB_O_DIRECT) {
+ mod_unixmode |= FILE_FLAG_NO_BUFFERING;
+ }
+
if ((wire_open_mode & SMB_O_DIRECTORY) ||
VALID_STAT_OF_DIR(smb_fname->st)) {
- if (access_mask != FILE_READ_DATA) {
+ 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;
}
- if (wire_open_mode & SMB_O_APPEND) {
- access_mask |= FILE_APPEND_DATA;
- }
- if (wire_open_mode & SMB_O_DIRECT) {
- mod_unixmode |= FILE_FLAG_NO_BUFFERING;
- }
DEBUG(10,("smb_posix_open: file %s, smb_posix_flags = %u, mode 0%o\n",
smb_fname_str_dbg(smb_fname),
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);
SSVAL(pdata, 0, 0);
}
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,
{
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 ((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);
if (req->wct < 8) {
reply_nterror(req, NT_STATUS_INVALID_PARAMETER);