Example #1
0
static int onefs_ntimes(vfs_handle_struct *handle, const char *fname,
			struct smb_file_time *ft)
{
	int flags = 0;
	struct timespec times[3];

	if (!null_timespec(ft->atime)) {
		flags |= VT_ATIME;
		times[0] = ft->atime;
		DEBUG(6,("**** onefs_ntimes: actime: %s.%d\n",
			time_to_asc(convert_timespec_to_time_t(ft->atime)),
			ft->atime.tv_nsec));
	}

	if (!null_timespec(ft->mtime)) {
		flags |= VT_MTIME;
		times[1] = ft->mtime;
		DEBUG(6,("**** onefs_ntimes: modtime: %s.%d\n",
			time_to_asc(convert_timespec_to_time_t(ft->mtime)),
			ft->mtime.tv_nsec));
	}

	if (!null_timespec(ft->create_time)) {
		flags |= VT_BTIME;
		times[2] = ft->create_time;
		DEBUG(6,("**** onefs_ntimes: createtime: %s.%d\n",
		   time_to_asc(convert_timespec_to_time_t(ft->create_time)),
		   ft->create_time.tv_nsec));
	}

	return onefs_vtimes_streams(handle, fname, flags, times);
}
Example #2
0
int file_ntimes(connection_struct *conn, const struct smb_filename *smb_fname,
		struct smb_file_time *ft)
{
	int ret = -1;

	errno = 0;

	DEBUG(6, ("file_ntime: actime: %s",
		  time_to_asc(convert_timespec_to_time_t(ft->atime))));
	DEBUG(6, ("file_ntime: modtime: %s",
		  time_to_asc(convert_timespec_to_time_t(ft->mtime))));
	DEBUG(6, ("file_ntime: ctime: %s",
		  time_to_asc(convert_timespec_to_time_t(ft->ctime))));
	DEBUG(6, ("file_ntime: createtime: %s",
		  time_to_asc(convert_timespec_to_time_t(ft->create_time))));

	/* Don't update the time on read-only shares */
	/* We need this as set_filetime (which can be called on
	   close and other paths) can end up calling this function
	   without the NEED_WRITE protection. Found by : 
	   Leo Weppelman <*****@*****.**>
	*/

	if (!CAN_WRITE(conn)) {
		return 0;
	}

	if(SMB_VFS_NTIMES(conn, smb_fname, ft) == 0) {
		return 0;
	}

	if((errno != EPERM) && (errno != EACCES)) {
		return -1;
	}

	if(!lp_dos_filetimes(SNUM(conn))) {
		return -1;
	}

	/* We have permission (given by the Samba admin) to
	   break POSIX semantics and allow a user to change
	   the time on a file they don't own but can write to
	   (as DOS does).
	 */

	/* Check if we have write access. */
	if (can_write_to_file(conn, smb_fname)) {
		/* We are allowed to become root and change the filetime. */
		become_root();
		ret = SMB_VFS_NTIMES(conn, smb_fname, ft);
		unbecome_root();
	}

	return ret;
}
Example #3
0
void set_close_write_time(struct files_struct *fsp, struct timespec ts)
{
	DEBUG(6,("close_write_time: %s" , time_to_asc(convert_timespec_to_time_t(ts))));

	if (null_timespec(ts)) {
		return;
	}
	fsp->write_time_forced = false;
	fsp->update_write_time_on_close = true;
	fsp->close_write_time = ts;
}
Example #4
0
static const char *tstring(TALLOC_CTX *ctx, time_t t)
{
	char *buf;
	buf = talloc_strdup(ctx, time_to_asc(t));
	if (!buf) {
		return "";
	}
	buf = talloc_all_string_sub(ctx,
			buf,
			" ",
			"&nbsp;");
	if (!buf) {
		return "";
	}
	return buf;
}
Example #5
0
void set_close_write_time(struct files_struct *fsp, struct timespec ts)
{
    DEBUG(6,("close_write_time: %s" , time_to_asc(convert_timespec_to_time_t(ts))));

    if (null_timespec(ts)) {
        return;
    }
    /*
     * if the write time on close is explict set, then don't
     * need to fix it up to the value in the locking db
     */
    fsp->write_time_forced = false;

    fsp->update_write_time_on_close = true;
    fsp->close_write_time = ts;
}
Example #6
0
static int traverse_fn1(const struct connections_key *key,
			const struct connections_data *crec,
			void *state)
{
	if (crec->cnum == -1)
		return 0;

	if (!process_exists(crec->pid) || !Ucrit_checkUid(crec->uid)) {
		return 0;
	}

	d_printf("%-10s   %s   %-12s  %s",
		 crec->servicename,procid_str_static(&crec->pid),
		 crec->machine,
		 time_to_asc(crec->start));

	return 0;
}
Example #7
0
static int show_share(struct db_record *rec,
		      const struct connections_key *key,
		      const struct connections_data *crec,
		      void *state)
{
	if (crec->cnum == -1)
		return 0;

	if (!process_exists(crec->pid)) {
		return 0;
	}

	d_printf("%-10.10s   %s   %-12s  %s",
	       crec->servicename, procid_str_static(&crec->pid),
	       crec->machine,
	       time_to_asc(crec->start));

	return 0;
}
Example #8
0
File: status.c Project: aosm/samba
static int traverse_fn1(TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA dbuf, void *state)
{
	struct connections_data crec;

	if (dbuf.dsize != sizeof(crec))
		return 0;

	memcpy(&crec, dbuf.dptr, sizeof(crec));

	if (crec.cnum == -1)
		return 0;

	if (!process_exists(crec.pid) || !Ucrit_checkUid(crec.uid)) {
		return 0;
	}

	d_printf("%-10s   %s   %-12s  %s",
	       crec.servicename,procid_str_static(&crec.pid),
	       crec.machine,
	       time_to_asc(crec.start));

	return 0;
}
Example #9
0
static bool get_ea_dos_attribute(connection_struct *conn,
				 struct smb_filename *smb_fname,
				 uint32 *pattr)
{
	struct xattr_DOSATTRIB dosattrib;
	enum ndr_err_code ndr_err;
	DATA_BLOB blob;
	ssize_t sizeret;
	fstring attrstr;
	uint32_t dosattr;

	if (!lp_store_dos_attributes(SNUM(conn))) {
		return False;
	}

	/* Don't reset pattr to zero as we may already have filename-based attributes we
	   need to preserve. */

	sizeret = SMB_VFS_GETXATTR(conn, smb_fname->base_name,
				   SAMBA_XATTR_DOS_ATTRIB, attrstr,
				   sizeof(attrstr));
	if (sizeret == -1) {
		if (errno == ENOSYS
#if defined(ENOTSUP)
			|| errno == ENOTSUP) {
#else
				) {
#endif
			DEBUG(1,("get_ea_dos_attribute: Cannot get attribute "
				 "from EA on file %s: Error = %s\n",
				 smb_fname_str_dbg(smb_fname),
				 strerror(errno)));
			set_store_dos_attributes(SNUM(conn), False);
		}
		return False;
	}

	blob.data = (uint8_t *)attrstr;
	blob.length = sizeret;

	ndr_err = ndr_pull_struct_blob(&blob, talloc_tos(), &dosattrib,
			(ndr_pull_flags_fn_t)ndr_pull_xattr_DOSATTRIB);

	if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
		DEBUG(1,("get_ea_dos_attribute: bad ndr decode "
			 "from EA on file %s: Error = %s\n",
			 smb_fname_str_dbg(smb_fname),
			 ndr_errstr(ndr_err)));
		return false;
	}

	DEBUG(10,("get_ea_dos_attribute: %s attr = %s\n",
		  smb_fname_str_dbg(smb_fname), dosattrib.attrib_hex));

	switch (dosattrib.version) {
		case 0xFFFF:
			dosattr = dosattrib.info.compatinfoFFFF.attrib;
			break;
		case 1:
			dosattr = dosattrib.info.info1.attrib;
			if (!null_nttime(dosattrib.info.info1.create_time)) {
				struct timespec create_time =
					nt_time_to_unix_timespec(
						dosattrib.info.info1.create_time);

				update_stat_ex_create_time(&smb_fname->st,
							create_time);

				DEBUG(10,("get_ea_dos_attribute: file %s case 1 "
					"set btime %s\n",
					smb_fname_str_dbg(smb_fname),
					time_to_asc(convert_timespec_to_time_t(
						create_time)) ));
			}
			break;
		case 2:
			dosattr = dosattrib.info.oldinfo2.attrib;
			/* Don't know what flags to check for this case. */
			break;
		case 3:
			dosattr = dosattrib.info.info3.attrib;
			if ((dosattrib.info.info3.valid_flags & XATTR_DOSINFO_CREATE_TIME) &&
					!null_nttime(dosattrib.info.info3.create_time)) {
				struct timespec create_time =
					nt_time_to_unix_timespec(
						dosattrib.info.info3.create_time);

				update_stat_ex_create_time(&smb_fname->st,
							create_time);

				DEBUG(10,("get_ea_dos_attribute: file %s case 3 "
					"set btime %s\n",
					smb_fname_str_dbg(smb_fname),
					time_to_asc(convert_timespec_to_time_t(
						create_time)) ));
			}
			break;
		default:
			DEBUG(1,("get_ea_dos_attribute: Badly formed DOSATTRIB on "
				 "file %s - %s\n", smb_fname_str_dbg(smb_fname),
				 attrstr));
	                return false;
	}

	if (S_ISDIR(smb_fname->st.st_ex_mode)) {
		dosattr |= FILE_ATTRIBUTE_DIRECTORY;
	}
	/* FILE_ATTRIBUTE_SPARSE is valid on get but not on set. */
	*pattr = (uint32)(dosattr & (SAMBA_ATTRIBUTES_MASK|FILE_ATTRIBUTE_SPARSE));

	DEBUG(8,("get_ea_dos_attribute returning (0x%x)", dosattr));

	if (dosattr & FILE_ATTRIBUTE_HIDDEN) DEBUG(8, ("h"));
	if (dosattr & FILE_ATTRIBUTE_READONLY ) DEBUG(8, ("r"));
	if (dosattr & FILE_ATTRIBUTE_SYSTEM) DEBUG(8, ("s"));
	if (dosattr & FILE_ATTRIBUTE_DIRECTORY   ) DEBUG(8, ("d"));
	if (dosattr & FILE_ATTRIBUTE_ARCHIVE  ) DEBUG(8, ("a"));

	DEBUG(8,("\n"));

	return True;
}

/****************************************************************************
 Set DOS attributes in an EA.
 Also sets the create time.
****************************************************************************/

static bool set_ea_dos_attribute(connection_struct *conn,
				 struct smb_filename *smb_fname,
				 uint32 dosmode)
{
	struct xattr_DOSATTRIB dosattrib;
	enum ndr_err_code ndr_err;
	DATA_BLOB blob;

	ZERO_STRUCT(dosattrib);
	ZERO_STRUCT(blob);

	dosattrib.version = 3;
	dosattrib.info.info3.valid_flags = XATTR_DOSINFO_ATTRIB|
					XATTR_DOSINFO_CREATE_TIME;
	dosattrib.info.info3.attrib = dosmode;
	dosattrib.info.info3.create_time = unix_timespec_to_nt_time(
				smb_fname->st.st_ex_btime);

	DEBUG(10,("set_ea_dos_attributes: set attribute 0x%x, btime = %s on file %s\n",
		(unsigned int)dosmode,
		time_to_asc(convert_timespec_to_time_t(smb_fname->st.st_ex_btime)),
		smb_fname_str_dbg(smb_fname) ));

	ndr_err = ndr_push_struct_blob(
			&blob, talloc_tos(), &dosattrib,
			(ndr_push_flags_fn_t)ndr_push_xattr_DOSATTRIB);

	if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
		DEBUG(5, ("create_acl_blob: ndr_push_xattr_DOSATTRIB failed: %s\n",
			ndr_errstr(ndr_err)));
		return false;
	}

	if (blob.data == NULL || blob.length == 0) {
		return false;
	}

	if (SMB_VFS_SETXATTR(conn, smb_fname->base_name,
			     SAMBA_XATTR_DOS_ATTRIB, blob.data, blob.length,
			     0) == -1) {
		bool ret = false;
		bool need_close = false;
		files_struct *fsp = NULL;

		if((errno != EPERM) && (errno != EACCES)) {
			if (errno == ENOSYS
#if defined(ENOTSUP)
				|| errno == ENOTSUP) {
#else
				) {
#endif
				DEBUG(1,("set_ea_dos_attributes: Cannot set "
					 "attribute EA on file %s: Error = %s\n",
					 smb_fname_str_dbg(smb_fname),
					 strerror(errno) ));
				set_store_dos_attributes(SNUM(conn), False);
			}
			return false;
		}

		/* We want DOS semantics, ie allow non owner with write permission to change the
			bits on a file. Just like file_ntimes below.
		*/

		/* Check if we have write access. */
		if(!CAN_WRITE(conn) || !lp_dos_filemode(SNUM(conn)))
			return false;

		if (!can_write_to_file(conn, smb_fname)) {
			return false;
		}

		/*
		 * We need to get an open file handle to do the
		 * metadata operation under root.
		 */

		if (!NT_STATUS_IS_OK(get_file_handle_for_metadata(conn,
						smb_fname,
						&fsp,
						&need_close))) {
			return false;
		}

		become_root();
		if (SMB_VFS_FSETXATTR(fsp,
				     SAMBA_XATTR_DOS_ATTRIB, blob.data,
				     blob.length, 0) == 0) {
			ret = true;
		}
		unbecome_root();
		if (need_close) {
			close_file(NULL, fsp, NORMAL_CLOSE);
		}
		return ret;
	}
	DEBUG(10,("set_ea_dos_attribute: set EA 0x%x on file %s\n",
		(unsigned int)dosmode,
		smb_fname_str_dbg(smb_fname)));
	return true;
}

/****************************************************************************
 Change a unix mode to a dos mode for an ms dfs link.
****************************************************************************/

uint32 dos_mode_msdfs(connection_struct *conn,
		      const struct smb_filename *smb_fname)
{
	uint32 result = 0;

	DEBUG(8,("dos_mode_msdfs: %s\n", smb_fname_str_dbg(smb_fname)));

	if (!VALID_STAT(smb_fname->st)) {
		return 0;
	}

	/* First do any modifications that depend on the path name. */
	/* hide files with a name starting with a . */
	if (lp_hide_dot_files(SNUM(conn))) {
		const char *p = strrchr_m(smb_fname->base_name, '/');
		if (p) {
			p++;
		} else {
			p = smb_fname->base_name;
		}

		/* Only . and .. are not hidden. */
		if (p[0] == '.' && !((p[1] == '\0') ||
				(p[1] == '.' && p[2] == '\0'))) {
			result |= FILE_ATTRIBUTE_HIDDEN;
		}
	}

	result |= dos_mode_from_sbuf(conn, smb_fname);

	/* Optimization : Only call is_hidden_path if it's not already
	   hidden. */
	if (!(result & FILE_ATTRIBUTE_HIDDEN) &&
	    IS_HIDDEN_PATH(conn, smb_fname->base_name)) {
		result |= FILE_ATTRIBUTE_HIDDEN;
	}

	if (result == 0) {
		result = FILE_ATTRIBUTE_NORMAL;
	}

	result = filter_mode_by_protocol(result);

	/*
	 * Add in that it is a reparse point
	 */
	result |= FILE_ATTRIBUTE_REPARSE_POINT;

	DEBUG(8,("dos_mode_msdfs returning "));

	if (result & FILE_ATTRIBUTE_HIDDEN) DEBUG(8, ("h"));
	if (result & FILE_ATTRIBUTE_READONLY ) DEBUG(8, ("r"));
	if (result & FILE_ATTRIBUTE_SYSTEM) DEBUG(8, ("s"));
	if (result & FILE_ATTRIBUTE_DIRECTORY   ) DEBUG(8, ("d"));
	if (result & FILE_ATTRIBUTE_ARCHIVE  ) DEBUG(8, ("a"));
	if (result & FILE_ATTRIBUTE_SPARSE ) DEBUG(8, ("[sparse]"));

	DEBUG(8,("\n"));

	return(result);
}
Example #10
0
static void print_share_mode(const struct share_mode_entry *e,
			     const char *sharepath,
			     const char *fname,
			     void *dummy)
{
	static int count;

	if (!is_valid_share_mode_entry(e)) {
		return;
	}

	if (!process_exists(e->pid)) {
		return;
	}

	if (count==0) {
		d_printf("Locked files:\n");
		d_printf("Pid          Uid        DenyMode   Access      R/W        Oplock           SharePath   Name   Time\n");
		d_printf("--------------------------------------------------------------------------------------------------\n");
	}
	count++;

	if (Ucrit_checkPid(e->pid)) {
		d_printf("%-11s  ",procid_str_static(&e->pid));
		d_printf("%-9u  ", (unsigned int)e->uid);
		switch (map_share_mode_to_deny_mode(e->share_access,
						    e->private_options)) {
			case DENY_NONE: d_printf("DENY_NONE  "); break;
			case DENY_ALL:  d_printf("DENY_ALL   "); break;
			case DENY_DOS:  d_printf("DENY_DOS   "); break;
			case DENY_READ: d_printf("DENY_READ  "); break;
			case DENY_WRITE:printf("DENY_WRITE "); break;
			case DENY_FCB:  d_printf("DENY_FCB "); break;
			default: {
				d_printf("unknown-please report ! "
					 "e->share_access = 0x%x, "
					 "e->private_options = 0x%x\n",
					 (unsigned int)e->share_access,
					 (unsigned int)e->private_options );
				break;
			}
		}
		d_printf("0x%-8x  ",(unsigned int)e->access_mask);
		if ((e->access_mask & (FILE_READ_DATA|FILE_WRITE_DATA))==
				(FILE_READ_DATA|FILE_WRITE_DATA)) {
			d_printf("RDWR       ");
		} else if (e->access_mask & FILE_WRITE_DATA) {
			d_printf("WRONLY     ");
		} else {
			d_printf("RDONLY     ");
		}

		if((e->op_type & (EXCLUSIVE_OPLOCK|BATCH_OPLOCK)) == 
					(EXCLUSIVE_OPLOCK|BATCH_OPLOCK)) {
			d_printf("EXCLUSIVE+BATCH ");
		} else if (e->op_type & EXCLUSIVE_OPLOCK) {
			d_printf("EXCLUSIVE       ");
		} else if (e->op_type & BATCH_OPLOCK) {
			d_printf("BATCH           ");
		} else if (e->op_type & LEVEL_II_OPLOCK) {
			d_printf("LEVEL_II        ");
		} else {
			d_printf("NONE            ");
		}

		d_printf(" %s   %s   %s",sharepath, fname, time_to_asc((time_t)e->time.tv_sec));
	}
}
Example #11
0
static int print_share_mode(const struct share_mode_entry *e,
			    const char *sharepath,
			    const char *fname,
			    const char *sname,
			    void *dummy)
{
	static int count;

	if (do_checks && !is_valid_share_mode_entry(e)) {
		return 0;
	}

	if (count==0) {
		d_printf("Locked files:\n");
		d_printf("Pid          Uid        DenyMode   Access      R/W        Oplock           SharePath   Name   Time\n");
		d_printf("--------------------------------------------------------------------------------------------------\n");
	}
	count++;

	if (do_checks && !serverid_exists(&e->pid)) {
		/* the process for this entry does not exist any more */
		return 0;
	}

	if (Ucrit_checkPid(e->pid)) {
		struct server_id_buf tmp;
		d_printf("%-11s  ", server_id_str_buf(e->pid, &tmp));
		d_printf("%-9u  ", (unsigned int)e->uid);
		switch (map_share_mode_to_deny_mode(e->share_access,
						    e->private_options)) {
			case DENY_NONE: d_printf("DENY_NONE  "); break;
			case DENY_ALL:  d_printf("DENY_ALL   "); break;
			case DENY_DOS:  d_printf("DENY_DOS   "); break;
			case DENY_READ: d_printf("DENY_READ  "); break;
			case DENY_WRITE:printf("DENY_WRITE "); break;
			case DENY_FCB:  d_printf("DENY_FCB "); break;
			default: {
				d_printf("unknown-please report ! "
					 "e->share_access = 0x%x, "
					 "e->private_options = 0x%x\n",
					 (unsigned int)e->share_access,
					 (unsigned int)e->private_options );
				break;
			}
		}
		d_printf("0x%-8x  ",(unsigned int)e->access_mask);
		if ((e->access_mask & (FILE_READ_DATA|FILE_WRITE_DATA))==
				(FILE_READ_DATA|FILE_WRITE_DATA)) {
			d_printf("RDWR       ");
		} else if (e->access_mask & FILE_WRITE_DATA) {
			d_printf("WRONLY     ");
		} else {
			d_printf("RDONLY     ");
		}

		if((e->op_type & (EXCLUSIVE_OPLOCK|BATCH_OPLOCK)) == 
					(EXCLUSIVE_OPLOCK|BATCH_OPLOCK)) {
			d_printf("EXCLUSIVE+BATCH ");
		} else if (e->op_type & EXCLUSIVE_OPLOCK) {
			d_printf("EXCLUSIVE       ");
		} else if (e->op_type & BATCH_OPLOCK) {
			d_printf("BATCH           ");
		} else if (e->op_type & LEVEL_II_OPLOCK) {
			d_printf("LEVEL_II        ");
		} else if (e->op_type == LEASE_OPLOCK) {
			uint32_t lstate = e->lease->current_state;
			d_printf("LEASE(%s%s%s)%s%s%s      ",
				 (lstate & SMB2_LEASE_READ)?"R":"",
				 (lstate & SMB2_LEASE_WRITE)?"W":"",
				 (lstate & SMB2_LEASE_HANDLE)?"H":"",
				 (lstate & SMB2_LEASE_READ)?"":" ",
				 (lstate & SMB2_LEASE_WRITE)?"":" ",
				 (lstate & SMB2_LEASE_HANDLE)?"":" ");
		} else {
			d_printf("NONE            ");
		}

		d_printf(" %s   %s%s   %s",
			 sharepath, fname,
			 sname ? sname : "",
			 time_to_asc((time_t)e->time.tv_sec));
	}

	return 0;
}
Example #12
0
static bool set_ea_dos_attribute(connection_struct *conn,
				 struct smb_filename *smb_fname,
				 uint32_t dosmode)
{
	struct xattr_DOSATTRIB dosattrib;
	enum ndr_err_code ndr_err;
	DATA_BLOB blob;

	ZERO_STRUCT(dosattrib);
	ZERO_STRUCT(blob);

	dosattrib.version = 3;
	dosattrib.info.info3.valid_flags = XATTR_DOSINFO_ATTRIB|
					XATTR_DOSINFO_CREATE_TIME;
	dosattrib.info.info3.attrib = dosmode;
	dosattrib.info.info3.create_time = unix_timespec_to_nt_time(
				smb_fname->st.st_ex_btime);

	DEBUG(10,("set_ea_dos_attributes: set attribute 0x%x, btime = %s on file %s\n",
		(unsigned int)dosmode,
		time_to_asc(convert_timespec_to_time_t(smb_fname->st.st_ex_btime)),
		smb_fname_str_dbg(smb_fname) ));

	ndr_err = ndr_push_struct_blob(
			&blob, talloc_tos(), &dosattrib,
			(ndr_push_flags_fn_t)ndr_push_xattr_DOSATTRIB);

	if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
		DEBUG(5, ("create_acl_blob: ndr_push_xattr_DOSATTRIB failed: %s\n",
			ndr_errstr(ndr_err)));
		return false;
	}

	if (blob.data == NULL || blob.length == 0) {
		return false;
	}

	if (SMB_VFS_SETXATTR(conn, smb_fname->base_name,
			     SAMBA_XATTR_DOS_ATTRIB, blob.data, blob.length,
			     0) == -1) {
		bool ret = false;
		bool need_close = false;
		files_struct *fsp = NULL;

		if((errno != EPERM) && (errno != EACCES)) {
			DBG_INFO("Cannot set "
				 "attribute EA on file %s: Error = %s\n",
				 smb_fname_str_dbg(smb_fname), strerror(errno));
			return false;
		}

		/* We want DOS semantics, ie allow non owner with write permission to change the
			bits on a file. Just like file_ntimes below.
		*/

		/* Check if we have write access. */
		if(!CAN_WRITE(conn) || !lp_dos_filemode(SNUM(conn)))
			return false;

		if (!can_write_to_file(conn, smb_fname)) {
			return false;
		}

		/*
		 * We need to get an open file handle to do the
		 * metadata operation under root.
		 */

		if (!NT_STATUS_IS_OK(get_file_handle_for_metadata(conn,
						smb_fname,
						&fsp,
						&need_close))) {
			return false;
		}

		become_root();
		if (SMB_VFS_FSETXATTR(fsp,
				     SAMBA_XATTR_DOS_ATTRIB, blob.data,
				     blob.length, 0) == 0) {
			ret = true;
		}
		unbecome_root();
		if (need_close) {
			close_file(NULL, fsp, NORMAL_CLOSE);
		}
		return ret;
	}
	DEBUG(10,("set_ea_dos_attribute: set EA 0x%x on file %s\n",
		(unsigned int)dosmode,
		smb_fname_str_dbg(smb_fname)));
	return true;
}
Example #13
0
static bool get_ea_dos_attribute(connection_struct *conn,
				 struct smb_filename *smb_fname,
				 uint32_t *pattr)
{
	struct xattr_DOSATTRIB dosattrib;
	enum ndr_err_code ndr_err;
	DATA_BLOB blob;
	ssize_t sizeret;
	fstring attrstr;
	uint32_t dosattr;

	if (!lp_store_dos_attributes(SNUM(conn))) {
		return False;
	}

	/* Don't reset pattr to zero as we may already have filename-based attributes we
	   need to preserve. */

	sizeret = SMB_VFS_GETXATTR(conn, smb_fname->base_name,
				   SAMBA_XATTR_DOS_ATTRIB, attrstr,
				   sizeof(attrstr));
	if (sizeret == -1) {
		DBG_INFO("Cannot get attribute "
			 "from EA on file %s: Error = %s\n",
			 smb_fname_str_dbg(smb_fname), strerror(errno));
		return False;
	}

	blob.data = (uint8_t *)attrstr;
	blob.length = sizeret;

	ndr_err = ndr_pull_struct_blob(&blob, talloc_tos(), &dosattrib,
			(ndr_pull_flags_fn_t)ndr_pull_xattr_DOSATTRIB);

	if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
		DEBUG(1,("get_ea_dos_attribute: bad ndr decode "
			 "from EA on file %s: Error = %s\n",
			 smb_fname_str_dbg(smb_fname),
			 ndr_errstr(ndr_err)));
		return false;
	}

	DEBUG(10,("get_ea_dos_attribute: %s attr = %s\n",
		  smb_fname_str_dbg(smb_fname), dosattrib.attrib_hex));

	switch (dosattrib.version) {
		case 0xFFFF:
			dosattr = dosattrib.info.compatinfoFFFF.attrib;
			break;
		case 1:
			dosattr = dosattrib.info.info1.attrib;
			if (!null_nttime(dosattrib.info.info1.create_time)) {
				struct timespec create_time =
					nt_time_to_unix_timespec(
						dosattrib.info.info1.create_time);

				update_stat_ex_create_time(&smb_fname->st,
							create_time);

				DEBUG(10,("get_ea_dos_attribute: file %s case 1 "
					"set btime %s\n",
					smb_fname_str_dbg(smb_fname),
					time_to_asc(convert_timespec_to_time_t(
						create_time)) ));
			}
			break;
		case 2:
			dosattr = dosattrib.info.oldinfo2.attrib;
			/* Don't know what flags to check for this case. */
			break;
		case 3:
			dosattr = dosattrib.info.info3.attrib;
			if ((dosattrib.info.info3.valid_flags & XATTR_DOSINFO_CREATE_TIME) &&
					!null_nttime(dosattrib.info.info3.create_time)) {
				struct timespec create_time =
					nt_time_to_unix_timespec(
						dosattrib.info.info3.create_time);

				update_stat_ex_create_time(&smb_fname->st,
							create_time);

				DEBUG(10,("get_ea_dos_attribute: file %s case 3 "
					"set btime %s\n",
					smb_fname_str_dbg(smb_fname),
					time_to_asc(convert_timespec_to_time_t(
						create_time)) ));
			}
			break;
		default:
			DEBUG(1,("get_ea_dos_attribute: Badly formed DOSATTRIB on "
				 "file %s - %s\n", smb_fname_str_dbg(smb_fname),
				 attrstr));
	                return false;
	}

	if (S_ISDIR(smb_fname->st.st_ex_mode)) {
		dosattr |= FILE_ATTRIBUTE_DIRECTORY;
	}
	/* FILE_ATTRIBUTE_SPARSE is valid on get but not on set. */
	*pattr |= (uint32_t)(dosattr & (SAMBA_ATTRIBUTES_MASK|FILE_ATTRIBUTE_SPARSE));

	dos_mode_debug_print(__func__, *pattr);

	return True;
}