mirror of
https://github.com/samba-team/samba.git
synced 2025-01-10 01:18:15 +03:00
r18009: Fixes bug 4026.
This completes the work Jeremy began last week, disambiguating the meaning of
c_time. (In POSIX terminology, c_time means "status Change time", not "create
time".) All uses of c_time, a_time and m_time have now been replaced with
change_time, access_time, and write_time, and when creation time is intended,
create_time is used.
Additionally, the capability of setting and retrieving the create time have
been added to the smbc_setxattr() and smbc_getxattr() functions. An example
of setting all four times can be seen with the program
examples/libsmbclient/testacl
with the following command line similar to:
testacl -f -S "system.*:CREATE_TIME:1000000000,ACCESS_TIME:1000000060,WRITE_TIME:1000000120,CHANGE_TIME:1000000180" 'smb://server/share/testfile.txt'
The -f option turns on the new mode which uses full time names in the
attribute specification (e.g. ACCESS_TIME vs A_TIME).
(This used to be commit 8e119b64f1
)
This commit is contained in:
parent
b7a5e3de1e
commit
5e44fc4cd4
@ -23,6 +23,7 @@ int main(int argc, const char *argv[])
|
||||
int flags;
|
||||
int debug = 0;
|
||||
int numeric = 0;
|
||||
int full_time_names = 0;
|
||||
enum acl_mode mode = SMB_ACL_GET;
|
||||
static char *the_acl = NULL;
|
||||
int ret;
|
||||
@ -42,6 +43,11 @@ int main(int argc, const char *argv[])
|
||||
"debug", 'd', POPT_ARG_INT, &debug,
|
||||
0, "Set debug level (0-100)"
|
||||
},
|
||||
{
|
||||
"full_time_names", 'f', POPT_ARG_NONE, &full_time_names,
|
||||
1,
|
||||
"Use new style xattr names, which include CREATE_TIME"
|
||||
},
|
||||
{
|
||||
"delete", 'D', POPT_ARG_STRING, NULL,
|
||||
'D', "Delete an acl", "ACL"
|
||||
@ -133,6 +139,11 @@ int main(int argc, const char *argv[])
|
||||
printf("Could not initialize smbc_ library\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (full_time_names) {
|
||||
SMBCCTX *context = smbc_set_context(NULL);
|
||||
smbc_option_set(context, "full_time_names", 1);
|
||||
}
|
||||
|
||||
/* Perform requested action */
|
||||
|
||||
@ -143,11 +154,11 @@ int main(int argc, const char *argv[])
|
||||
{
|
||||
if (numeric)
|
||||
{
|
||||
the_acl = "system.nt_sec_desc.*";
|
||||
the_acl = "system.*";
|
||||
}
|
||||
else
|
||||
{
|
||||
the_acl = "system.nt_sec_desc.*+";
|
||||
the_acl = "system.*+";
|
||||
}
|
||||
}
|
||||
ret = smbc_getxattr(path, the_acl, value, sizeof(value));
|
||||
|
@ -80,6 +80,15 @@ struct smbc_internal_data {
|
||||
*/
|
||||
BOOL _debug_stderr;
|
||||
|
||||
/*
|
||||
* Support "Create Time" in get/set with the *xattr() functions, if
|
||||
* true. This replaces the dos attribute strings C_TIME, A_TIME and
|
||||
* M_TIME with CHANGE_TIME, ACCESS_TIME and WRITE_TIME, and adds
|
||||
* CREATE_TIME. Default is FALSE, i.e. to use the old-style shorter
|
||||
* names and to not support CREATE time, for backward compatibility.
|
||||
*/
|
||||
BOOL _full_time_names;
|
||||
|
||||
/*
|
||||
* Authentication function which includes the context. This will be
|
||||
* used if set; otherwise context->callbacks.auth_fn() will be used.
|
||||
|
@ -1252,7 +1252,7 @@ void set_ctimespec(SMB_STRUCT_STAT *pst, struct timespec ts)
|
||||
pst->st_ctime = ts.tv_sec;
|
||||
#else
|
||||
#if defined(HAVE_STAT_ST_CTIM)
|
||||
pst->st_atim = ts;
|
||||
pst->st_ctim = ts;
|
||||
#elif defined(HAVE_STAT_ST_CTIMENSEC)
|
||||
pst->st_ctime = ts.tv_sec;
|
||||
pst->st_ctimensec = ts.tv_nsec
|
||||
|
@ -1179,7 +1179,9 @@ BOOL cli_posix_getlock(struct cli_state *cli, int fnum, SMB_BIG_UINT *poffset, S
|
||||
|
||||
BOOL cli_getattrE(struct cli_state *cli, int fd,
|
||||
uint16 *attr, SMB_OFF_T *size,
|
||||
time_t *c_time, time_t *a_time, time_t *m_time)
|
||||
time_t *change_time,
|
||||
time_t *access_time,
|
||||
time_t *write_time)
|
||||
{
|
||||
memset(cli->outbuf,'\0',smb_size);
|
||||
memset(cli->inbuf,'\0',smb_size);
|
||||
@ -1209,16 +1211,16 @@ BOOL cli_getattrE(struct cli_state *cli, int fd,
|
||||
*attr = SVAL(cli->inbuf,smb_vwv10);
|
||||
}
|
||||
|
||||
if (c_time) {
|
||||
*c_time = cli_make_unix_date2(cli, cli->inbuf+smb_vwv0);
|
||||
if (change_time) {
|
||||
*change_time = cli_make_unix_date2(cli, cli->inbuf+smb_vwv0);
|
||||
}
|
||||
|
||||
if (a_time) {
|
||||
*a_time = cli_make_unix_date2(cli, cli->inbuf+smb_vwv2);
|
||||
if (access_time) {
|
||||
*access_time = cli_make_unix_date2(cli, cli->inbuf+smb_vwv2);
|
||||
}
|
||||
|
||||
if (m_time) {
|
||||
*m_time = cli_make_unix_date2(cli, cli->inbuf+smb_vwv4);
|
||||
if (write_time) {
|
||||
*write_time = cli_make_unix_date2(cli, cli->inbuf+smb_vwv4);
|
||||
}
|
||||
|
||||
return True;
|
||||
@ -1229,7 +1231,7 @@ BOOL cli_getattrE(struct cli_state *cli, int fd,
|
||||
****************************************************************************/
|
||||
|
||||
BOOL cli_getatr(struct cli_state *cli, const char *fname,
|
||||
uint16 *attr, SMB_OFF_T *size, time_t *t)
|
||||
uint16 *attr, SMB_OFF_T *size, time_t *write_time)
|
||||
{
|
||||
char *p;
|
||||
|
||||
@ -1261,8 +1263,8 @@ BOOL cli_getatr(struct cli_state *cli, const char *fname,
|
||||
*size = IVAL(cli->inbuf, smb_vwv3);
|
||||
}
|
||||
|
||||
if (t) {
|
||||
*t = cli_make_unix_date3(cli, cli->inbuf+smb_vwv1);
|
||||
if (write_time) {
|
||||
*write_time = cli_make_unix_date3(cli, cli->inbuf+smb_vwv1);
|
||||
}
|
||||
|
||||
if (attr) {
|
||||
@ -1278,7 +1280,9 @@ BOOL cli_getatr(struct cli_state *cli, const char *fname,
|
||||
****************************************************************************/
|
||||
|
||||
BOOL cli_setattrE(struct cli_state *cli, int fd,
|
||||
time_t c_time, time_t a_time, time_t m_time)
|
||||
time_t change_time,
|
||||
time_t access_time,
|
||||
time_t write_time)
|
||||
|
||||
{
|
||||
char *p;
|
||||
@ -1293,9 +1297,9 @@ BOOL cli_setattrE(struct cli_state *cli, int fd,
|
||||
cli_setup_packet(cli);
|
||||
|
||||
SSVAL(cli->outbuf,smb_vwv0, fd);
|
||||
cli_put_dos_date2(cli, cli->outbuf,smb_vwv1, c_time);
|
||||
cli_put_dos_date2(cli, cli->outbuf,smb_vwv3, a_time);
|
||||
cli_put_dos_date2(cli, cli->outbuf,smb_vwv5, m_time);
|
||||
cli_put_dos_date2(cli, cli->outbuf,smb_vwv1, change_time);
|
||||
cli_put_dos_date2(cli, cli->outbuf,smb_vwv3, access_time);
|
||||
cli_put_dos_date2(cli, cli->outbuf,smb_vwv5, write_time);
|
||||
|
||||
p = smb_buf(cli->outbuf);
|
||||
*p++ = 4;
|
||||
|
@ -379,7 +379,9 @@ BOOL cli_oem_change_password(struct cli_state *cli, const char *user, const char
|
||||
send a qpathinfo call
|
||||
****************************************************************************/
|
||||
BOOL cli_qpathinfo(struct cli_state *cli, const char *fname,
|
||||
time_t *c_time, time_t *a_time, time_t *m_time,
|
||||
time_t *change_time,
|
||||
time_t *access_time,
|
||||
time_t *write_time,
|
||||
SMB_OFF_T *size, uint16 *mode)
|
||||
{
|
||||
unsigned int data_len = 0;
|
||||
@ -434,14 +436,14 @@ BOOL cli_qpathinfo(struct cli_state *cli, const char *fname,
|
||||
date_fn = cli_make_unix_date2;
|
||||
}
|
||||
|
||||
if (c_time) {
|
||||
*c_time = date_fn(cli, rdata+0);
|
||||
if (change_time) {
|
||||
*change_time = date_fn(cli, rdata+0);
|
||||
}
|
||||
if (a_time) {
|
||||
*a_time = date_fn(cli, rdata+4);
|
||||
if (access_time) {
|
||||
*access_time = date_fn(cli, rdata+4);
|
||||
}
|
||||
if (m_time) {
|
||||
*m_time = date_fn(cli, rdata+8);
|
||||
if (write_time) {
|
||||
*write_time = date_fn(cli, rdata+8);
|
||||
}
|
||||
if (size) {
|
||||
*size = IVAL(rdata, 12);
|
||||
@ -460,7 +462,11 @@ BOOL cli_qpathinfo(struct cli_state *cli, const char *fname,
|
||||
send a setpathinfo call
|
||||
****************************************************************************/
|
||||
BOOL cli_setpathinfo(struct cli_state *cli, const char *fname,
|
||||
time_t c_time, time_t a_time, time_t m_time, uint16 mode)
|
||||
time_t create_time,
|
||||
time_t access_time,
|
||||
time_t write_time,
|
||||
time_t change_time,
|
||||
uint16 mode)
|
||||
{
|
||||
unsigned int data_len = 0;
|
||||
unsigned int param_len = 0;
|
||||
@ -495,16 +501,16 @@ BOOL cli_setpathinfo(struct cli_state *cli, const char *fname,
|
||||
* Add the create, last access, modification, and status change times
|
||||
*/
|
||||
|
||||
/* Don't set create time, at offset 0 */
|
||||
put_long_date(p, create_time);
|
||||
p += 8;
|
||||
|
||||
put_long_date(p, a_time);
|
||||
put_long_date(p, access_time);
|
||||
p += 8;
|
||||
|
||||
put_long_date(p, m_time);
|
||||
put_long_date(p, write_time);
|
||||
p += 8;
|
||||
|
||||
put_long_date(p, c_time);
|
||||
put_long_date(p, change_time);
|
||||
p += 8;
|
||||
|
||||
/* Add attributes */
|
||||
@ -555,8 +561,11 @@ send a qpathinfo call with the SMB_QUERY_FILE_ALL_INFO info level
|
||||
****************************************************************************/
|
||||
|
||||
BOOL cli_qpathinfo2(struct cli_state *cli, const char *fname,
|
||||
struct timespec *create_time, struct timespec *access_time, struct timespec *write_time,
|
||||
struct timespec *change_time, SMB_OFF_T *size, uint16 *mode,
|
||||
struct timespec *create_time,
|
||||
struct timespec *access_time,
|
||||
struct timespec *write_time,
|
||||
struct timespec *change_time,
|
||||
SMB_OFF_T *size, uint16 *mode,
|
||||
SMB_INO_T *ino)
|
||||
{
|
||||
unsigned int data_len = 0;
|
||||
@ -670,8 +679,11 @@ send a qfileinfo call
|
||||
****************************************************************************/
|
||||
BOOL cli_qfileinfo(struct cli_state *cli, int fnum,
|
||||
uint16 *mode, SMB_OFF_T *size,
|
||||
struct timespec *create_time, struct timespec *access_time, struct timespec *write_time,
|
||||
struct timespec *change_time, SMB_INO_T *ino)
|
||||
struct timespec *create_time,
|
||||
struct timespec *access_time,
|
||||
struct timespec *write_time,
|
||||
struct timespec *change_time,
|
||||
SMB_INO_T *ino)
|
||||
{
|
||||
unsigned int data_len = 0;
|
||||
unsigned int param_len = 0;
|
||||
|
@ -33,9 +33,10 @@
|
||||
typedef struct DOS_ATTR_DESC {
|
||||
int mode;
|
||||
SMB_OFF_T size;
|
||||
time_t a_time;
|
||||
time_t c_time;
|
||||
time_t m_time;
|
||||
time_t create_time;
|
||||
time_t access_time;
|
||||
time_t write_time;
|
||||
time_t change_time;
|
||||
SMB_INO_T inode;
|
||||
} DOS_ATTR_DESC;
|
||||
|
||||
@ -1470,15 +1471,16 @@ smbc_getatr(SMBCCTX * context,
|
||||
char *path,
|
||||
uint16 *mode,
|
||||
SMB_OFF_T *size,
|
||||
struct timespec *c_time_ts,
|
||||
struct timespec *a_time_ts,
|
||||
struct timespec *m_time_ts,
|
||||
struct timespec *create_time_ts,
|
||||
struct timespec *access_time_ts,
|
||||
struct timespec *write_time_ts,
|
||||
struct timespec *change_time_ts,
|
||||
SMB_INO_T *ino)
|
||||
{
|
||||
pstring fixedpath;
|
||||
pstring targetpath;
|
||||
struct cli_state *targetcli;
|
||||
time_t m_time;
|
||||
time_t write_time;
|
||||
|
||||
if (!context || !context->internal ||
|
||||
!context->internal->_initialized) {
|
||||
@ -1515,7 +1517,11 @@ smbc_getatr(SMBCCTX * context,
|
||||
|
||||
if (!srv->no_pathinfo2 &&
|
||||
cli_qpathinfo2(targetcli, targetpath,
|
||||
NULL, a_time_ts, m_time_ts, c_time_ts, size, mode, ino)) {
|
||||
create_time_ts,
|
||||
access_time_ts,
|
||||
write_time_ts,
|
||||
change_time_ts,
|
||||
size, mode, ino)) {
|
||||
return True;
|
||||
}
|
||||
|
||||
@ -1525,12 +1531,28 @@ smbc_getatr(SMBCCTX * context,
|
||||
return False;
|
||||
}
|
||||
|
||||
if (cli_getatr(targetcli, targetpath, mode, size, &m_time)) {
|
||||
if (m_time_ts != NULL) {
|
||||
*m_time_ts = convert_time_t_to_timespec(m_time);
|
||||
if (a_time_ts != NULL) *a_time_ts = *m_time_ts;
|
||||
if (c_time_ts != NULL) *c_time_ts = *m_time_ts;
|
||||
if (cli_getatr(targetcli, targetpath, mode, size, &write_time)) {
|
||||
|
||||
struct timespec w_time_ts;
|
||||
|
||||
w_time_ts = convert_time_t_to_timespec(write_time);
|
||||
|
||||
if (write_time_ts != NULL) {
|
||||
*write_time_ts = w_time_ts;
|
||||
}
|
||||
|
||||
if (create_time_ts != NULL) {
|
||||
*create_time_ts = w_time_ts;
|
||||
}
|
||||
|
||||
if (access_time_ts != NULL) {
|
||||
*access_time_ts = w_time_ts;
|
||||
}
|
||||
|
||||
if (change_time_ts != NULL) {
|
||||
*change_time_ts = w_time_ts;
|
||||
}
|
||||
|
||||
srv->no_pathinfo2 = True;
|
||||
return True;
|
||||
}
|
||||
@ -1552,7 +1574,10 @@ smbc_getatr(SMBCCTX * context,
|
||||
*/
|
||||
static BOOL
|
||||
smbc_setatr(SMBCCTX * context, SMBCSRV *srv, char *path,
|
||||
time_t c_time, time_t a_time, time_t m_time,
|
||||
time_t create_time,
|
||||
time_t access_time,
|
||||
time_t write_time,
|
||||
time_t change_time,
|
||||
uint16 mode)
|
||||
{
|
||||
int fd;
|
||||
@ -1565,7 +1590,12 @@ smbc_setatr(SMBCCTX * context, SMBCSRV *srv, char *path,
|
||||
* attributes manipulated.
|
||||
*/
|
||||
if (srv->no_pathinfo ||
|
||||
! cli_setpathinfo(srv->cli, path, c_time, a_time, m_time, mode)) {
|
||||
! cli_setpathinfo(srv->cli, path,
|
||||
create_time,
|
||||
access_time,
|
||||
write_time,
|
||||
change_time,
|
||||
mode)) {
|
||||
|
||||
/*
|
||||
* setpathinfo is not supported; go to plan B.
|
||||
@ -1587,42 +1617,14 @@ smbc_setatr(SMBCCTX * context, SMBCSRV *srv, char *path,
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the creat time of the file (if it wasn't provided).
|
||||
* We'll need it in the set call
|
||||
*/
|
||||
if (c_time == 0) {
|
||||
ret = cli_getattrE(srv->cli, fd,
|
||||
NULL, NULL,
|
||||
&c_time, NULL, NULL);
|
||||
} else {
|
||||
ret = True;
|
||||
}
|
||||
|
||||
/* If we got create time, set times */
|
||||
if (ret) {
|
||||
/* Some OS versions don't support create time */
|
||||
if (c_time == 0 || c_time == -1) {
|
||||
c_time = time(NULL);
|
||||
}
|
||||
/* Set the new attributes */
|
||||
ret = cli_setattrE(srv->cli, fd,
|
||||
change_time,
|
||||
access_time,
|
||||
write_time);
|
||||
|
||||
/*
|
||||
* For sanity sake, since there is no POSIX function
|
||||
* to set the create time of a file, if the existing
|
||||
* create time is greater than either of access time
|
||||
* or modification time, set create time to the
|
||||
* smallest of those. This ensure that the create
|
||||
* time of a file is never greater than its last
|
||||
* access or modification time.
|
||||
*/
|
||||
if (c_time > a_time) c_time = a_time;
|
||||
if (c_time > m_time) c_time = m_time;
|
||||
|
||||
/* Set the new attributes */
|
||||
ret = cli_setattrE(srv->cli, fd,
|
||||
c_time, a_time, m_time);
|
||||
cli_close(srv->cli, fd);
|
||||
}
|
||||
/* Close the file */
|
||||
cli_close(srv->cli, fd);
|
||||
|
||||
/*
|
||||
* Unfortunately, setattrE() doesn't have a provision for
|
||||
@ -1711,11 +1713,17 @@ smbc_unlink_ctx(SMBCCTX *context,
|
||||
int saverr = errno;
|
||||
SMB_OFF_T size = 0;
|
||||
uint16 mode = 0;
|
||||
struct timespec m_time_ts, a_time_ts, c_time_ts;
|
||||
struct timespec write_time_ts;
|
||||
struct timespec access_time_ts;
|
||||
struct timespec change_time_ts;
|
||||
SMB_INO_T ino = 0;
|
||||
|
||||
if (!smbc_getatr(context, srv, path, &mode, &size,
|
||||
&c_time_ts, &a_time_ts, &m_time_ts, &ino)) {
|
||||
NULL,
|
||||
&access_time_ts,
|
||||
&write_time_ts,
|
||||
&change_time_ts,
|
||||
&ino)) {
|
||||
|
||||
/* Hmmm, bad error ... What? */
|
||||
|
||||
@ -2051,9 +2059,9 @@ smbc_stat_ctx(SMBCCTX *context,
|
||||
fstring password;
|
||||
fstring workgroup;
|
||||
pstring path;
|
||||
struct timespec m_time_ts;
|
||||
struct timespec a_time_ts;
|
||||
struct timespec c_time_ts;
|
||||
struct timespec write_time_ts;
|
||||
struct timespec access_time_ts;
|
||||
struct timespec change_time_ts;
|
||||
SMB_OFF_T size = 0;
|
||||
uint16 mode = 0;
|
||||
SMB_INO_T ino = 0;
|
||||
@ -2097,7 +2105,11 @@ smbc_stat_ctx(SMBCCTX *context,
|
||||
}
|
||||
|
||||
if (!smbc_getatr(context, srv, path, &mode, &size,
|
||||
&c_time_ts, &a_time_ts, &m_time_ts, &ino)) {
|
||||
NULL,
|
||||
&access_time_ts,
|
||||
&write_time_ts,
|
||||
&change_time_ts,
|
||||
&ino)) {
|
||||
|
||||
errno = smbc_errno(context, srv->cli);
|
||||
return -1;
|
||||
@ -2108,9 +2120,9 @@ smbc_stat_ctx(SMBCCTX *context,
|
||||
|
||||
smbc_setup_stat(context, st, path, size, mode);
|
||||
|
||||
set_atimespec(st, a_time_ts);
|
||||
set_ctimespec(st, c_time_ts);
|
||||
set_mtimespec(st, m_time_ts);
|
||||
set_atimespec(st, access_time_ts);
|
||||
set_ctimespec(st, change_time_ts);
|
||||
set_mtimespec(st, write_time_ts);
|
||||
st->st_dev = srv->dev;
|
||||
|
||||
return 0;
|
||||
@ -2126,9 +2138,9 @@ smbc_fstat_ctx(SMBCCTX *context,
|
||||
SMBCFILE *file,
|
||||
struct stat *st)
|
||||
{
|
||||
struct timespec c_time_ts;
|
||||
struct timespec a_time_ts;
|
||||
struct timespec m_time_ts;
|
||||
struct timespec change_time_ts;
|
||||
struct timespec access_time_ts;
|
||||
struct timespec write_time_ts;
|
||||
SMB_OFF_T size;
|
||||
uint16 mode;
|
||||
fstring server;
|
||||
@ -2184,26 +2196,33 @@ smbc_fstat_ctx(SMBCCTX *context,
|
||||
/*d_printf(">>>fstat: resolved path as %s\n", targetpath);*/
|
||||
|
||||
if (!cli_qfileinfo(targetcli, file->cli_fd, &mode, &size,
|
||||
NULL, &a_time_ts, &m_time_ts, &c_time_ts, &ino)) {
|
||||
time_t c_time, a_time, m_time;
|
||||
NULL,
|
||||
&access_time_ts,
|
||||
&write_time_ts,
|
||||
&change_time_ts,
|
||||
&ino)) {
|
||||
|
||||
time_t change_time, access_time, write_time;
|
||||
|
||||
if (!cli_getattrE(targetcli, file->cli_fd, &mode, &size,
|
||||
&c_time, &a_time, &m_time)) {
|
||||
&change_time, &access_time, &write_time)) {
|
||||
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
c_time_ts = convert_time_t_to_timespec(c_time);
|
||||
a_time_ts = convert_time_t_to_timespec(a_time);
|
||||
m_time_ts = convert_time_t_to_timespec(m_time);
|
||||
|
||||
change_time_ts = convert_time_t_to_timespec(change_time);
|
||||
access_time_ts = convert_time_t_to_timespec(access_time);
|
||||
write_time_ts = convert_time_t_to_timespec(write_time);
|
||||
}
|
||||
|
||||
st->st_ino = ino;
|
||||
|
||||
smbc_setup_stat(context, st, file->fname, size, mode);
|
||||
|
||||
set_atimespec(st, a_time_ts);
|
||||
set_ctimespec(st, c_time_ts);
|
||||
set_mtimespec(st, m_time_ts);
|
||||
set_atimespec(st, access_time_ts);
|
||||
set_ctimespec(st, change_time_ts);
|
||||
set_mtimespec(st, write_time_ts);
|
||||
st->st_dev = file->srv->dev;
|
||||
|
||||
return 0;
|
||||
@ -2902,7 +2921,7 @@ smbc_opendir_ctx(SMBCCTX *context,
|
||||
|
||||
if (smbc_getatr(context, srv, path,
|
||||
&mode, NULL,
|
||||
NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL,
|
||||
NULL) &&
|
||||
! IS_DOS_DIR(mode)) {
|
||||
|
||||
@ -3592,8 +3611,8 @@ smbc_utimes_ctx(SMBCCTX *context,
|
||||
fstring password;
|
||||
fstring workgroup;
|
||||
pstring path;
|
||||
time_t a_time;
|
||||
time_t m_time;
|
||||
time_t access_time;
|
||||
time_t write_time;
|
||||
|
||||
if (!context || !context->internal ||
|
||||
!context->internal->_initialized) {
|
||||
@ -3611,10 +3630,10 @@ smbc_utimes_ctx(SMBCCTX *context,
|
||||
}
|
||||
|
||||
if (tbuf == NULL) {
|
||||
a_time = m_time = time(NULL);
|
||||
access_time = write_time = time(NULL);
|
||||
} else {
|
||||
a_time = tbuf[0].tv_sec;
|
||||
m_time = tbuf[1].tv_sec;
|
||||
access_time = tbuf[0].tv_sec;
|
||||
write_time = tbuf[1].tv_sec;
|
||||
}
|
||||
|
||||
if (DEBUGLVL(4))
|
||||
@ -3623,13 +3642,13 @@ smbc_utimes_ctx(SMBCCTX *context,
|
||||
char atimebuf[32];
|
||||
char mtimebuf[32];
|
||||
|
||||
strncpy(atimebuf, ctime(&a_time), sizeof(atimebuf) - 1);
|
||||
strncpy(atimebuf, ctime(&access_time), sizeof(atimebuf) - 1);
|
||||
atimebuf[sizeof(atimebuf) - 1] = '\0';
|
||||
if ((p = strchr(atimebuf, '\n')) != NULL) {
|
||||
*p = '\0';
|
||||
}
|
||||
|
||||
strncpy(mtimebuf, ctime(&m_time), sizeof(mtimebuf) - 1);
|
||||
strncpy(mtimebuf, ctime(&write_time), sizeof(mtimebuf) - 1);
|
||||
mtimebuf[sizeof(mtimebuf) - 1] = '\0';
|
||||
if ((p = strchr(mtimebuf, '\n')) != NULL) {
|
||||
*p = '\0';
|
||||
@ -3660,7 +3679,8 @@ smbc_utimes_ctx(SMBCCTX *context,
|
||||
return -1; /* errno set by smbc_server */
|
||||
}
|
||||
|
||||
if (!smbc_setatr(context, srv, path, 0, a_time, m_time, 0)) {
|
||||
if (!smbc_setatr(context, srv, path,
|
||||
0, access_time, write_time, 0, 0)) {
|
||||
return -1; /* errno set by smbc_setatr */
|
||||
}
|
||||
|
||||
@ -4085,7 +4105,10 @@ dos_attr_query(SMBCCTX *context,
|
||||
const char *filename,
|
||||
SMBCSRV *srv)
|
||||
{
|
||||
struct timespec m_time_ts, a_time_ts, c_time_ts;
|
||||
struct timespec create_time_ts;
|
||||
struct timespec write_time_ts;
|
||||
struct timespec access_time_ts;
|
||||
struct timespec change_time_ts;
|
||||
SMB_OFF_T size = 0;
|
||||
uint16 mode = 0;
|
||||
SMB_INO_T inode = 0;
|
||||
@ -4100,7 +4123,11 @@ dos_attr_query(SMBCCTX *context,
|
||||
/* Obtain the DOS attributes */
|
||||
if (!smbc_getatr(context, srv, CONST_DISCARD(char *, filename),
|
||||
&mode, &size,
|
||||
&c_time_ts, &a_time_ts, &m_time_ts, &inode)) {
|
||||
&create_time_ts,
|
||||
&access_time_ts,
|
||||
&write_time_ts,
|
||||
&change_time_ts,
|
||||
&inode)) {
|
||||
|
||||
errno = smbc_errno(context, srv->cli);
|
||||
DEBUG(5, ("dos_attr_query Failed to query old attributes\n"));
|
||||
@ -4110,9 +4137,10 @@ dos_attr_query(SMBCCTX *context,
|
||||
|
||||
ret->mode = mode;
|
||||
ret->size = size;
|
||||
ret->a_time = convert_timespec_to_time_t(a_time_ts);
|
||||
ret->c_time = convert_timespec_to_time_t(c_time_ts);
|
||||
ret->m_time = convert_timespec_to_time_t(m_time_ts);
|
||||
ret->create_time = convert_timespec_to_time_t(create_time_ts);
|
||||
ret->access_time = convert_timespec_to_time_t(access_time_ts);
|
||||
ret->write_time = convert_timespec_to_time_t(write_time_ts);
|
||||
ret->change_time = convert_timespec_to_time_t(change_time_ts);
|
||||
ret->inode = inode;
|
||||
|
||||
return ret;
|
||||
@ -4126,8 +4154,40 @@ dos_attr_parse(SMBCCTX *context,
|
||||
SMBCSRV *srv,
|
||||
char *str)
|
||||
{
|
||||
const char *p = str;
|
||||
int n;
|
||||
const char *p = str;
|
||||
fstring tok;
|
||||
struct {
|
||||
const char * create_time_attr;
|
||||
const char * access_time_attr;
|
||||
const char * write_time_attr;
|
||||
const char * change_time_attr;
|
||||
} attr_strings;
|
||||
|
||||
/* Determine whether to use old-style or new-style attribute names */
|
||||
if (context->internal->_full_time_names) {
|
||||
/* new-style names */
|
||||
attr_strings.create_time_attr = "CREATE_TIME";
|
||||
attr_strings.access_time_attr = "ACCESS_TIME";
|
||||
attr_strings.write_time_attr = "WRITE_TIME";
|
||||
attr_strings.change_time_attr = "CHANGE_TIME";
|
||||
} else {
|
||||
/* old-style names */
|
||||
attr_strings.create_time_attr = NULL;
|
||||
attr_strings.access_time_attr = "A_TIME";
|
||||
attr_strings.write_time_attr = "M_TIME";
|
||||
attr_strings.change_time_attr = "C_TIME";
|
||||
}
|
||||
|
||||
/* if this is to set the entire ACL... */
|
||||
if (*str == '*') {
|
||||
/* ... then increment past the first colon if there is one */
|
||||
if ((p = strchr(str, ':')) != NULL) {
|
||||
++p;
|
||||
} else {
|
||||
p = str;
|
||||
}
|
||||
}
|
||||
|
||||
while (next_token(&p, tok, "\t,\r\n", sizeof(tok))) {
|
||||
|
||||
@ -4141,18 +4201,28 @@ dos_attr_parse(SMBCCTX *context,
|
||||
continue;
|
||||
}
|
||||
|
||||
if (StrnCaseCmp(tok, "A_TIME:", 7) == 0) {
|
||||
dad->a_time = (time_t)strtol(tok+7, NULL, 10);
|
||||
n = strlen(attr_strings.access_time_attr);
|
||||
if (StrnCaseCmp(tok, attr_strings.access_time_attr, n) == 0) {
|
||||
dad->access_time = (time_t)strtol(tok+n+1, NULL, 10);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (StrnCaseCmp(tok, "C_TIME:", 7) == 0) {
|
||||
dad->c_time = (time_t)strtol(tok+7, NULL, 10);
|
||||
n = strlen(attr_strings.change_time_attr);
|
||||
if (StrnCaseCmp(tok, attr_strings.change_time_attr, n) == 0) {
|
||||
dad->change_time = (time_t)strtol(tok+n+1, NULL, 10);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (StrnCaseCmp(tok, "M_TIME:", 7) == 0) {
|
||||
dad->m_time = (time_t)strtol(tok+7, NULL, 10);
|
||||
n = strlen(attr_strings.write_time_attr);
|
||||
if (StrnCaseCmp(tok, attr_strings.write_time_attr, n) == 0) {
|
||||
dad->write_time = (time_t)strtol(tok+n+1, NULL, 10);
|
||||
continue;
|
||||
}
|
||||
|
||||
n = strlen(attr_strings.create_time_attr);
|
||||
if (attr_strings.create_time_attr != NULL &&
|
||||
StrnCaseCmp(tok, attr_strings.create_time_attr, n) == 0) {
|
||||
dad->create_time = (time_t)strtol(tok+n+1, NULL, 10);
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -4193,9 +4263,10 @@ cacl_get(SMBCCTX *context,
|
||||
BOOL exclude_nt_acl = False;
|
||||
BOOL exclude_dos_mode = False;
|
||||
BOOL exclude_dos_size = False;
|
||||
BOOL exclude_dos_ctime = False;
|
||||
BOOL exclude_dos_atime = False;
|
||||
BOOL exclude_dos_mtime = False;
|
||||
BOOL exclude_dos_create_time = False;
|
||||
BOOL exclude_dos_access_time = False;
|
||||
BOOL exclude_dos_write_time = False;
|
||||
BOOL exclude_dos_change_time = False;
|
||||
BOOL exclude_dos_inode = False;
|
||||
BOOL numeric = True;
|
||||
BOOL determine_size = (bufsize == 0);
|
||||
@ -4206,12 +4277,55 @@ cacl_get(SMBCCTX *context,
|
||||
char *name;
|
||||
char *pExclude;
|
||||
char *p;
|
||||
struct timespec m_time_ts, a_time_ts, c_time_ts;
|
||||
time_t m_time = (time_t)0, a_time = (time_t)0, c_time = (time_t)0;
|
||||
struct timespec create_time_ts;
|
||||
struct timespec write_time_ts;
|
||||
struct timespec access_time_ts;
|
||||
struct timespec change_time_ts;
|
||||
time_t create_time = (time_t)0;
|
||||
time_t write_time = (time_t)0;
|
||||
time_t access_time = (time_t)0;
|
||||
time_t change_time = (time_t)0;
|
||||
SMB_OFF_T size = 0;
|
||||
uint16 mode = 0;
|
||||
SMB_INO_T ino = 0;
|
||||
struct cli_state *cli = srv->cli;
|
||||
struct {
|
||||
const char * create_time_attr;
|
||||
const char * access_time_attr;
|
||||
const char * write_time_attr;
|
||||
const char * change_time_attr;
|
||||
} attr_strings;
|
||||
struct {
|
||||
const char * create_time_attr;
|
||||
const char * access_time_attr;
|
||||
const char * write_time_attr;
|
||||
const char * change_time_attr;
|
||||
} excl_attr_strings;
|
||||
|
||||
/* Determine whether to use old-style or new-style attribute names */
|
||||
if (context->internal->_full_time_names) {
|
||||
/* new-style names */
|
||||
attr_strings.create_time_attr = "CREATE_TIME";
|
||||
attr_strings.access_time_attr = "ACCESS_TIME";
|
||||
attr_strings.write_time_attr = "WRITE_TIME";
|
||||
attr_strings.change_time_attr = "CHANGE_TIME";
|
||||
|
||||
excl_attr_strings.create_time_attr = "CREATE_TIME";
|
||||
excl_attr_strings.access_time_attr = "ACCESS_TIME";
|
||||
excl_attr_strings.write_time_attr = "WRITE_TIME";
|
||||
excl_attr_strings.change_time_attr = "CHANGE_TIME";
|
||||
} else {
|
||||
/* old-style names */
|
||||
attr_strings.create_time_attr = NULL;
|
||||
attr_strings.access_time_attr = "A_TIME";
|
||||
attr_strings.write_time_attr = "M_TIME";
|
||||
attr_strings.change_time_attr = "C_TIME";
|
||||
|
||||
excl_attr_strings.create_time_attr = NULL;
|
||||
excl_attr_strings.access_time_attr = "dos_attr.A_TIME";
|
||||
excl_attr_strings.write_time_attr = "dos_attr.M_TIME";
|
||||
excl_attr_strings.change_time_attr = "dos_attr.C_TIME";
|
||||
}
|
||||
|
||||
/* Copy name so we can strip off exclusions (if any are specified) */
|
||||
strncpy(name_sandbox, attr_name, sizeof(name_sandbox) - 1);
|
||||
@ -4269,14 +4383,22 @@ cacl_get(SMBCCTX *context,
|
||||
else if (StrCaseCmp(pExclude, "dos_attr.size") == 0) {
|
||||
exclude_dos_size = True;
|
||||
}
|
||||
else if (StrCaseCmp(pExclude, "dos_attr.c_time") == 0) {
|
||||
exclude_dos_ctime = True;
|
||||
else if (excl_attr_strings.create_time_attr != NULL &&
|
||||
StrCaseCmp(pExclude,
|
||||
excl_attr_strings.change_time_attr) == 0) {
|
||||
exclude_dos_create_time = True;
|
||||
}
|
||||
else if (StrCaseCmp(pExclude, "dos_attr.a_time") == 0) {
|
||||
exclude_dos_atime = True;
|
||||
else if (StrCaseCmp(pExclude,
|
||||
excl_attr_strings.access_time_attr) == 0) {
|
||||
exclude_dos_access_time = True;
|
||||
}
|
||||
else if (StrCaseCmp(pExclude, "dos_attr.m_time") == 0) {
|
||||
exclude_dos_mtime = True;
|
||||
else if (StrCaseCmp(pExclude,
|
||||
excl_attr_strings.write_time_attr) == 0) {
|
||||
exclude_dos_write_time = True;
|
||||
}
|
||||
else if (StrCaseCmp(pExclude,
|
||||
excl_attr_strings.change_time_attr) == 0) {
|
||||
exclude_dos_change_time = True;
|
||||
}
|
||||
else if (StrCaseCmp(pExclude, "dos_attr.inode") == 0) {
|
||||
exclude_dos_inode = True;
|
||||
@ -4554,15 +4676,21 @@ cacl_get(SMBCCTX *context,
|
||||
|
||||
/* Obtain the DOS attributes */
|
||||
if (!smbc_getatr(context, srv, filename, &mode, &size,
|
||||
&c_time_ts, &a_time_ts, &m_time_ts, &ino)) {
|
||||
&create_time_ts,
|
||||
&access_time_ts,
|
||||
&write_time_ts,
|
||||
&change_time_ts,
|
||||
&ino)) {
|
||||
|
||||
errno = smbc_errno(context, srv->cli);
|
||||
return -1;
|
||||
|
||||
}
|
||||
c_time = convert_timespec_to_time_t(c_time_ts);
|
||||
a_time = convert_timespec_to_time_t(a_time_ts);
|
||||
m_time = convert_timespec_to_time_t(m_time_ts);
|
||||
|
||||
create_time = convert_timespec_to_time_t(create_time_ts);
|
||||
access_time = convert_timespec_to_time_t(access_time_ts);
|
||||
write_time = convert_timespec_to_time_t(write_time_ts);
|
||||
change_time = convert_timespec_to_time_t(change_time_ts);
|
||||
|
||||
if (! exclude_dos_mode) {
|
||||
if (all || all_dos) {
|
||||
@ -4655,12 +4783,14 @@ cacl_get(SMBCCTX *context,
|
||||
bufsize -= n;
|
||||
}
|
||||
|
||||
if (! exclude_dos_ctime) {
|
||||
if (! exclude_dos_create_time &&
|
||||
attr_strings.create_time_attr != NULL) {
|
||||
if (all || all_dos) {
|
||||
if (determine_size) {
|
||||
p = talloc_asprintf(ctx,
|
||||
",C_TIME:%lu",
|
||||
c_time);
|
||||
",%s:%lu",
|
||||
attr_strings.create_time_attr,
|
||||
create_time);
|
||||
if (!p) {
|
||||
errno = ENOMEM;
|
||||
return -1;
|
||||
@ -4668,11 +4798,13 @@ cacl_get(SMBCCTX *context,
|
||||
n = strlen(p);
|
||||
} else {
|
||||
n = snprintf(buf, bufsize,
|
||||
",C_TIME:%lu", c_time);
|
||||
",%s:%lu",
|
||||
attr_strings.create_time_attr,
|
||||
create_time);
|
||||
}
|
||||
} else if (StrCaseCmp(name, "c_time") == 0) {
|
||||
} else if (StrCaseCmp(name, attr_strings.create_time_attr) == 0) {
|
||||
if (determine_size) {
|
||||
p = talloc_asprintf(ctx, "%lu", c_time);
|
||||
p = talloc_asprintf(ctx, "%lu", create_time);
|
||||
if (!p) {
|
||||
errno = ENOMEM;
|
||||
return -1;
|
||||
@ -4680,7 +4812,7 @@ cacl_get(SMBCCTX *context,
|
||||
n = strlen(p);
|
||||
} else {
|
||||
n = snprintf(buf, bufsize,
|
||||
"%lu", c_time);
|
||||
"%lu", create_time);
|
||||
}
|
||||
}
|
||||
|
||||
@ -4693,12 +4825,13 @@ cacl_get(SMBCCTX *context,
|
||||
bufsize -= n;
|
||||
}
|
||||
|
||||
if (! exclude_dos_atime) {
|
||||
if (! exclude_dos_access_time) {
|
||||
if (all || all_dos) {
|
||||
if (determine_size) {
|
||||
p = talloc_asprintf(ctx,
|
||||
",A_TIME:%lu",
|
||||
a_time);
|
||||
",%s:%lu",
|
||||
attr_strings.access_time_attr,
|
||||
access_time);
|
||||
if (!p) {
|
||||
errno = ENOMEM;
|
||||
return -1;
|
||||
@ -4706,11 +4839,13 @@ cacl_get(SMBCCTX *context,
|
||||
n = strlen(p);
|
||||
} else {
|
||||
n = snprintf(buf, bufsize,
|
||||
",A_TIME:%lu", a_time);
|
||||
",%s:%lu",
|
||||
attr_strings.access_time_attr,
|
||||
access_time);
|
||||
}
|
||||
} else if (StrCaseCmp(name, "a_time") == 0) {
|
||||
} else if (StrCaseCmp(name, attr_strings.access_time_attr) == 0) {
|
||||
if (determine_size) {
|
||||
p = talloc_asprintf(ctx, "%lu", a_time);
|
||||
p = talloc_asprintf(ctx, "%lu", access_time);
|
||||
if (!p) {
|
||||
errno = ENOMEM;
|
||||
return -1;
|
||||
@ -4718,7 +4853,7 @@ cacl_get(SMBCCTX *context,
|
||||
n = strlen(p);
|
||||
} else {
|
||||
n = snprintf(buf, bufsize,
|
||||
"%lu", a_time);
|
||||
"%lu", access_time);
|
||||
}
|
||||
}
|
||||
|
||||
@ -4731,12 +4866,13 @@ cacl_get(SMBCCTX *context,
|
||||
bufsize -= n;
|
||||
}
|
||||
|
||||
if (! exclude_dos_mtime) {
|
||||
if (! exclude_dos_write_time) {
|
||||
if (all || all_dos) {
|
||||
if (determine_size) {
|
||||
p = talloc_asprintf(ctx,
|
||||
",M_TIME:%lu",
|
||||
m_time);
|
||||
",%s:%lu",
|
||||
attr_strings.write_time_attr,
|
||||
write_time);
|
||||
if (!p) {
|
||||
errno = ENOMEM;
|
||||
return -1;
|
||||
@ -4744,11 +4880,13 @@ cacl_get(SMBCCTX *context,
|
||||
n = strlen(p);
|
||||
} else {
|
||||
n = snprintf(buf, bufsize,
|
||||
",M_TIME:%lu", m_time);
|
||||
",%s:%lu",
|
||||
attr_strings.write_time_attr,
|
||||
write_time);
|
||||
}
|
||||
} else if (StrCaseCmp(name, "m_time") == 0) {
|
||||
} else if (StrCaseCmp(name, attr_strings.write_time_attr) == 0) {
|
||||
if (determine_size) {
|
||||
p = talloc_asprintf(ctx, "%lu", m_time);
|
||||
p = talloc_asprintf(ctx, "%lu", write_time);
|
||||
if (!p) {
|
||||
errno = ENOMEM;
|
||||
return -1;
|
||||
@ -4756,7 +4894,48 @@ cacl_get(SMBCCTX *context,
|
||||
n = strlen(p);
|
||||
} else {
|
||||
n = snprintf(buf, bufsize,
|
||||
"%lu", m_time);
|
||||
"%lu", write_time);
|
||||
}
|
||||
}
|
||||
|
||||
if (!determine_size && n > bufsize) {
|
||||
errno = ERANGE;
|
||||
return -1;
|
||||
}
|
||||
buf += n;
|
||||
n_used += n;
|
||||
bufsize -= n;
|
||||
}
|
||||
|
||||
if (! exclude_dos_change_time) {
|
||||
if (all || all_dos) {
|
||||
if (determine_size) {
|
||||
p = talloc_asprintf(ctx,
|
||||
",%s:%lu",
|
||||
attr_strings.change_time_attr,
|
||||
change_time);
|
||||
if (!p) {
|
||||
errno = ENOMEM;
|
||||
return -1;
|
||||
}
|
||||
n = strlen(p);
|
||||
} else {
|
||||
n = snprintf(buf, bufsize,
|
||||
",%s:%lu",
|
||||
attr_strings.change_time_attr,
|
||||
change_time);
|
||||
}
|
||||
} else if (StrCaseCmp(name, attr_strings.change_time_attr) == 0) {
|
||||
if (determine_size) {
|
||||
p = talloc_asprintf(ctx, "%lu", change_time);
|
||||
if (!p) {
|
||||
errno = ENOMEM;
|
||||
return -1;
|
||||
}
|
||||
n = strlen(p);
|
||||
} else {
|
||||
n = snprintf(buf, bufsize,
|
||||
"%lu", change_time);
|
||||
}
|
||||
}
|
||||
|
||||
@ -5046,6 +5225,12 @@ smbc_setxattr_ctx(SMBCCTX *context,
|
||||
TALLOC_CTX *ctx;
|
||||
POLICY_HND pol;
|
||||
DOS_ATTR_DESC *dad;
|
||||
struct {
|
||||
const char * create_time_attr;
|
||||
const char * access_time_attr;
|
||||
const char * write_time_attr;
|
||||
const char * change_time_attr;
|
||||
} attr_strings;
|
||||
|
||||
if (!context || !context->internal ||
|
||||
!context->internal->_initialized) {
|
||||
@ -5135,9 +5320,10 @@ smbc_setxattr_ctx(SMBCCTX *context,
|
||||
|
||||
/* Set the new DOS attributes */
|
||||
if (! smbc_setatr(context, srv, path,
|
||||
dad->c_time,
|
||||
dad->a_time,
|
||||
dad->m_time,
|
||||
dad->create_time,
|
||||
dad->access_time,
|
||||
dad->write_time,
|
||||
dad->change_time,
|
||||
dad->mode)) {
|
||||
|
||||
/* cause failure if NT failed too */
|
||||
@ -5245,14 +5431,31 @@ smbc_setxattr_ctx(SMBCCTX *context,
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Determine whether to use old-style or new-style attribute names */
|
||||
if (context->internal->_full_time_names) {
|
||||
/* new-style names */
|
||||
attr_strings.create_time_attr = "system.dos_attr.CREATE_TIME";
|
||||
attr_strings.access_time_attr = "system.dos_attr.ACCESS_TIME";
|
||||
attr_strings.write_time_attr = "system.dos_attr.WRITE_TIME";
|
||||
attr_strings.change_time_attr = "system.dos_attr.CHANGE_TIME";
|
||||
} else {
|
||||
/* old-style names */
|
||||
attr_strings.create_time_attr = NULL;
|
||||
attr_strings.access_time_attr = "system.dos_attr.A_TIME";
|
||||
attr_strings.write_time_attr = "system.dos_attr.M_TIME";
|
||||
attr_strings.change_time_attr = "system.dos_attr.C_TIME";
|
||||
}
|
||||
|
||||
/*
|
||||
* Are they asking to set a DOS attribute?
|
||||
*/
|
||||
if (StrCaseCmp(name, "system.dos_attr.*") == 0 ||
|
||||
StrCaseCmp(name, "system.dos_attr.mode") == 0 ||
|
||||
StrCaseCmp(name, "system.dos_attr.c_time") == 0 ||
|
||||
StrCaseCmp(name, "system.dos_attr.a_time") == 0 ||
|
||||
StrCaseCmp(name, "system.dos_attr.m_time") == 0) {
|
||||
(attr_strings.create_time_attr != NULL &&
|
||||
StrCaseCmp(name, attr_strings.create_time_attr) == 0) ||
|
||||
StrCaseCmp(name, attr_strings.access_time_attr) == 0 ||
|
||||
StrCaseCmp(name, attr_strings.write_time_attr) == 0 ||
|
||||
StrCaseCmp(name, attr_strings.change_time_attr) == 0) {
|
||||
|
||||
/* get a DOS Attribute Descriptor with current attributes */
|
||||
dad = dos_attr_query(context, ctx, path, srv);
|
||||
@ -5269,9 +5472,10 @@ smbc_setxattr_ctx(SMBCCTX *context,
|
||||
|
||||
/* Set the new DOS attributes */
|
||||
ret2 = smbc_setatr(context, srv, path,
|
||||
dad->c_time,
|
||||
dad->a_time,
|
||||
dad->m_time,
|
||||
dad->create_time,
|
||||
dad->access_time,
|
||||
dad->write_time,
|
||||
dad->change_time,
|
||||
dad->mode);
|
||||
|
||||
/* ret2 has True (success) / False (failure) */
|
||||
@ -5313,6 +5517,12 @@ smbc_getxattr_ctx(SMBCCTX *context,
|
||||
pstring path;
|
||||
TALLOC_CTX *ctx;
|
||||
POLICY_HND pol;
|
||||
struct {
|
||||
const char * create_time_attr;
|
||||
const char * access_time_attr;
|
||||
const char * write_time_attr;
|
||||
const char * change_time_attr;
|
||||
} attr_strings;
|
||||
|
||||
|
||||
if (!context || !context->internal ||
|
||||
@ -5369,6 +5579,21 @@ smbc_getxattr_ctx(SMBCCTX *context,
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Determine whether to use old-style or new-style attribute names */
|
||||
if (context->internal->_full_time_names) {
|
||||
/* new-style names */
|
||||
attr_strings.create_time_attr = "system.dos_attr.CREATE_TIME";
|
||||
attr_strings.access_time_attr = "system.dos_attr.ACCESS_TIME";
|
||||
attr_strings.write_time_attr = "system.dos_attr.WRITE_TIME";
|
||||
attr_strings.change_time_attr = "system.dos_attr.CHANGE_TIME";
|
||||
} else {
|
||||
/* old-style names */
|
||||
attr_strings.create_time_attr = NULL;
|
||||
attr_strings.access_time_attr = "system.dos_attr.A_TIME";
|
||||
attr_strings.write_time_attr = "system.dos_attr.M_TIME";
|
||||
attr_strings.change_time_attr = "system.dos_attr.C_TIME";
|
||||
}
|
||||
|
||||
/* Are they requesting a supported attribute? */
|
||||
if (StrCaseCmp(name, "system.*") == 0 ||
|
||||
StrnCaseCmp(name, "system.*!", 9) == 0 ||
|
||||
@ -5389,9 +5614,11 @@ smbc_getxattr_ctx(SMBCCTX *context,
|
||||
StrnCaseCmp(name, "system.dos_attr.*!", 18) == 0 ||
|
||||
StrCaseCmp(name, "system.dos_attr.mode") == 0 ||
|
||||
StrCaseCmp(name, "system.dos_attr.size") == 0 ||
|
||||
StrCaseCmp(name, "system.dos_attr.c_time") == 0 ||
|
||||
StrCaseCmp(name, "system.dos_attr.a_time") == 0 ||
|
||||
StrCaseCmp(name, "system.dos_attr.m_time") == 0 ||
|
||||
(attr_strings.create_time_attr != NULL &&
|
||||
StrCaseCmp(name, attr_strings.create_time_attr) == 0) ||
|
||||
StrCaseCmp(name, attr_strings.access_time_attr) == 0 ||
|
||||
StrCaseCmp(name, attr_strings.write_time_attr) == 0 ||
|
||||
StrCaseCmp(name, attr_strings.change_time_attr) == 0 ||
|
||||
StrCaseCmp(name, "system.dos_attr.inode") == 0) {
|
||||
|
||||
/* Yup. */
|
||||
@ -5536,7 +5763,7 @@ smbc_listxattr_ctx(SMBCCTX *context,
|
||||
* the complete set of attribute names, always, rather than only those
|
||||
* attribute names which actually exist for a file. Hmmm...
|
||||
*/
|
||||
const char supported[] =
|
||||
const char supported_old[] =
|
||||
"system.*\0"
|
||||
"system.*+\0"
|
||||
"system.nt_sec_desc.revision\0"
|
||||
@ -5555,6 +5782,33 @@ smbc_listxattr_ctx(SMBCCTX *context,
|
||||
"system.dos_attr.a_time\0"
|
||||
"system.dos_attr.m_time\0"
|
||||
;
|
||||
const char supported_new[] =
|
||||
"system.*\0"
|
||||
"system.*+\0"
|
||||
"system.nt_sec_desc.revision\0"
|
||||
"system.nt_sec_desc.owner\0"
|
||||
"system.nt_sec_desc.owner+\0"
|
||||
"system.nt_sec_desc.group\0"
|
||||
"system.nt_sec_desc.group+\0"
|
||||
"system.nt_sec_desc.acl.*\0"
|
||||
"system.nt_sec_desc.acl\0"
|
||||
"system.nt_sec_desc.acl+\0"
|
||||
"system.nt_sec_desc.*\0"
|
||||
"system.nt_sec_desc.*+\0"
|
||||
"system.dos_attr.*\0"
|
||||
"system.dos_attr.mode\0"
|
||||
"system.dos_attr.create_time\0"
|
||||
"system.dos_attr.access_time\0"
|
||||
"system.dos_attr.write_time\0"
|
||||
"system.dos_attr.change_time\0"
|
||||
;
|
||||
const char * supported;
|
||||
|
||||
if (context->internal->_full_time_names) {
|
||||
supported = supported_new;
|
||||
} else {
|
||||
supported = supported_old;
|
||||
}
|
||||
|
||||
if (size == 0) {
|
||||
return sizeof(supported);
|
||||
@ -6029,24 +6283,17 @@ smbc_option_set(SMBCCTX *context,
|
||||
option_value.b = (BOOL) va_arg(ap, int);
|
||||
context->internal->_debug_stderr = option_value.b;
|
||||
|
||||
} else if (strcmp(option_name, "debug_to_stderr") == 0) {
|
||||
} else if (strcmp(option_name, "full_time_names") == 0) {
|
||||
/*
|
||||
* Log to standard error instead of standard output.
|
||||
*
|
||||
* This function used to take a third parameter,
|
||||
* void *option_value. Since it was a void* and we needed to
|
||||
* pass a boolean, a boolean value was cast to void* to be
|
||||
* passed in. Now that we're using a va_list to retrieve the
|
||||
* parameters, the casting kludge is unnecessary.
|
||||
*
|
||||
* WARNING: DO NOT USE THIS OPTION.
|
||||
* This option is retained for backward compatibility. New
|
||||
* applications should use "debug_to_stderr" and properly pass
|
||||
* in a boolean (int) value.
|
||||
* Use new-style time attribute names, e.g. WRITE_TIME rather
|
||||
* than the old-style names such as M_TIME. This allows also
|
||||
* setting/getting CREATE_TIME which was previously
|
||||
* unimplemented. (Note that the old C_TIME was supposed to
|
||||
* be CHANGE_TIME but was confused and sometimes referred to
|
||||
* CREATE_TIME.)
|
||||
*/
|
||||
option_value.v = va_arg(ap, void *);
|
||||
context->internal->_debug_stderr =
|
||||
(option_value.v == NULL ? False : True);
|
||||
option_value.b = (BOOL) va_arg(ap, int);
|
||||
context->internal->_full_time_names = option_value.b;
|
||||
|
||||
} else if (strcmp(option_name, "auth_function") == 0) {
|
||||
/*
|
||||
@ -6086,6 +6333,21 @@ smbc_option_get(SMBCCTX *context,
|
||||
#else
|
||||
return (void *) context->internal->_debug_stderr;
|
||||
#endif
|
||||
} else if (strcmp(option_name, "full_time_names") == 0) {
|
||||
/*
|
||||
* Use new-style time attribute names, e.g. WRITE_TIME rather
|
||||
* than the old-style names such as M_TIME. This allows also
|
||||
* setting/getting CREATE_TIME which was previously
|
||||
* unimplemented. (Note that the old C_TIME was supposed to
|
||||
* be CHANGE_TIME but was confused and sometimes referred to
|
||||
* CREATE_TIME.)
|
||||
*/
|
||||
#if defined(__intptr_t_defined) || defined(HAVE_INTPTR_T)
|
||||
return (void *) (intptr_t) context->internal->_full_time_names;
|
||||
#else
|
||||
return (void *) context->internal->_full_time_names;
|
||||
#endif
|
||||
|
||||
} else if (strcmp(option_name, "auth_function") == 0) {
|
||||
/*
|
||||
* Use the new-style authentication function which includes
|
||||
|
Loading…
Reference in New Issue
Block a user