diff options
Diffstat (limited to 'source3')
-rw-r--r-- | source3/include/smb.h | 6 | ||||
-rw-r--r-- | source3/libsmb/clifile.c | 105 | ||||
-rw-r--r-- | source3/torture/torture.c | 55 |
3 files changed, 161 insertions, 5 deletions
diff --git a/source3/include/smb.h b/source3/include/smb.h index 6c2f74e3b9..add57ddcf4 100644 --- a/source3/include/smb.h +++ b/source3/include/smb.h @@ -1659,4 +1659,10 @@ typedef struct smb_sign_info { BOOL mandatory_signing; } smb_sign_info; +struct ea_struct { + uint8 flags; + char *name; + DATA_BLOB value; +}; + #endif /* _SMB_H */ diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c index 6641d6b056..23c98c16f3 100644 --- a/source3/libsmb/clifile.c +++ b/source3/libsmb/clifile.c @@ -1166,7 +1166,7 @@ NTSTATUS cli_raw_ioctl(struct cli_state *cli, int fnum, uint32 code, DATA_BLOB * Set an extended attribute on a pathname. *********************************************************/ -BOOL cli_set_ea(struct cli_state *cli, const char *path, const char *ea_name, const char *ea_val, size_t ea_len) +BOOL cli_set_path_ea(struct cli_state *cli, const char *path, const char *ea_name, const char *ea_val, size_t ea_len) { unsigned int data_len = 0; unsigned int param_len = 0; @@ -1185,25 +1185,82 @@ BOOL cli_set_ea(struct cli_state *cli, const char *path, const char *ea_name, co p += clistr_push(cli, p, path, MIN(srclen, sizeof(param)-6), STR_TERMINATE); param_len = PTR_DIFF(p, param); - data_len = 4 + ea_namelen + 1 + ea_len; + data_len = 4 + 4 + ea_namelen + 1 + ea_len; data = malloc(data_len); if (!data) { return False; } p = data; + SIVAL(p,0,data_len); + p += 4; SCVAL(p, 0, 0); /* EA flags. */ SCVAL(p, 1, ea_namelen); SSVAL(p, 2, ea_len); memcpy(p+4, ea_name, ea_namelen+1); /* Copy in the name. */ memcpy(p+4+ea_namelen+1, ea_val, ea_len); - data_len = 4 + ea_namelen + 1 + ea_len; if (!cli_send_trans(cli, SMBtrans2, NULL, /* name */ -1, 0, /* fid, flags */ &setup, 1, 0, /* setup, length, max */ param, param_len, 2, /* param, length, max */ - (char *)&data, data_len, cli->max_xmit /* data, length, max */ + data, data_len, cli->max_xmit /* data, length, max */ + )) { + return False; + } + + if (!cli_receive_trans(cli, SMBtrans2, + &rparam, ¶m_len, + &rdata, &data_len)) { + return False; + } + + SAFE_FREE(data); + SAFE_FREE(rdata); + SAFE_FREE(rparam); + + return True; +} + +/********************************************************* + Set an extended attribute on an fnum. +*********************************************************/ + +BOOL cli_set_fnum_ea(struct cli_state *cli, int fnum, const char *ea_name, const char *ea_val, size_t ea_len) +{ + unsigned int data_len = 0; + unsigned int param_len = 6; + uint16 setup = TRANSACT2_SETFILEINFO; + pstring param; + char *data = NULL; + char *rparam=NULL, *rdata=NULL; + char *p; + size_t ea_namelen = strlen(ea_name); + + memset(param, 0, sizeof(param)); + SSVAL(param,0,fnum); + SSVAL(param,2,SMB_INFO_SET_EA); + + data_len = 4 + 4 + ea_namelen + 1 + ea_len; + data = malloc(data_len); + if (!data) { + return False; + } + p = data; + SIVAL(p,0,data_len); + p += 4; + SCVAL(p, 0, 0); /* EA flags. */ + SCVAL(p, 1, ea_namelen); + SSVAL(p, 2, ea_len); + memcpy(p+4, ea_name, ea_namelen+1); /* Copy in the name. */ + memcpy(p+4+ea_namelen+1, ea_val, ea_len); + + if (!cli_send_trans(cli, SMBtrans2, + NULL, /* name */ + -1, 0, /* fid, flags */ + &setup, 1, 0, /* setup, length, max */ + param, param_len, 2, /* param, length, max */ + data, data_len, cli->max_xmit /* data, length, max */ )) { return False; } @@ -1221,7 +1278,45 @@ BOOL cli_set_ea(struct cli_state *cli, const char *path, const char *ea_name, co return True; } -BOOL cli_get_ea(struct cli_state *cli, const char *path, const char *ea_name, char **value, size_t *val_len) +BOOL cli_get_eas(struct cli_state *cli, const char *path, + TALLOC_CTX *ctx, + size_t *pnum_eas, + struct ea_struct **ea_list) { + unsigned int data_len = 0; + unsigned int param_len = 0; + unsigned int rparam_len, rdata_len; + uint16 setup = TRANSACT2_QPATHINFO; + pstring param; + char *rparam=NULL, *rdata=NULL; + char *p; + + p = param; + memset(p, 0, 6); + SSVAL(p, 0, SMB_INFO_QUERY_ALL_EAS); + p += 6; + p += clistr_push(cli, p, path, sizeof(pstring)-6, STR_TERMINATE); + + param_len = PTR_DIFF(p, param); + + if (!cli_send_trans(cli, SMBtrans2, + NULL, /* Name */ + -1, 0, /* fid, flags */ + &setup, 1, 0, /* setup, length, max */ + param, param_len, 10, /* param, length, max */ + NULL, data_len, cli->max_xmit /* data, length, max */ + )) { + return False; + } + + if (!cli_receive_trans(cli, SMBtrans2, + &rparam, &rparam_len, + &rdata, &rdata_len)) { + return False; + } + + if (!rdata || rdata_len < 4) { + return False; + } return False; } diff --git a/source3/torture/torture.c b/source3/torture/torture.c index 07d568e879..3a250c1e14 100644 --- a/source3/torture/torture.c +++ b/source3/torture/torture.c @@ -4310,8 +4310,62 @@ BOOL torture_chkpath_test(int dummy) return ret; } +static BOOL run_eatest(int dummy) +{ + static struct cli_state *cli; + const char *fname = "\\eatest.txt"; + BOOL correct = True; + int fnum, i; + + printf("starting eatest\n"); + + if (!torture_open_connection(&cli)) { + return False; + } + + cli_unlink(cli, fname); + fnum = cli_nt_create_full(cli, fname, 0, + FIRST_DESIRED_ACCESS, FILE_ATTRIBUTE_ARCHIVE, + FILE_SHARE_NONE, FILE_OVERWRITE_IF, + 0x4044, 0); + + if (fnum == -1) { + printf("open failed - %s\n", cli_errstr(cli)); + return False; + } + for (i = 0; i < 10; i++) { + fstring ea_name, ea_val; + slprintf(ea_name, sizeof(ea_name), "EA_%d", i); + memset(ea_val, (char)i+1, i+1); + if (!cli_set_fnum_ea(cli, fnum, ea_name, ea_val, i+1)) { + printf("ea_set of name %s failed - %s\n", ea_name, cli_errstr(cli)); + return False; + } + } + + cli_close(cli, fnum); + for (i = 0; i < 10; i++) { + fstring ea_name, ea_val; + + slprintf(ea_name, sizeof(ea_name), "EA_%d", i); + memset(ea_val, (char)i+1, i+1); + if (!cli_set_path_ea(cli, fname, ea_name, ea_val, i+1)) { + printf("ea_set of name %s failed - %s\n", ea_name, cli_errstr(cli)); + return False; + } + } + + + cli_get_eas(cli, fname, NULL,NULL,NULL); + + if (!torture_close_connection(cli)) { + correct = False; + } + + return correct; +} static BOOL run_dirtest1(int dummy) { @@ -4650,6 +4704,7 @@ static struct { {"IOCTL", torture_ioctl_test, 0}, {"CHKPATH", torture_chkpath_test, 0}, {"FDSESS", run_fdsesstest, 0}, + { "EATEST", run_eatest, 0}, {NULL, NULL, 0}}; |