1
0
mirror of https://github.com/samba-team/samba.git synced 2024-12-25 23:21:54 +03:00

Fix get/set of EA's in client library. Added torture test for it.

Jeremy.
This commit is contained in:
Jeremy Allison 0001-01-01 00:00:00 +00:00
parent 9cb6b10efa
commit 0d239a9c07
2 changed files with 182 additions and 80 deletions

View File

@ -1163,28 +1163,18 @@ NTSTATUS cli_raw_ioctl(struct cli_state *cli, int fnum, uint32 code, DATA_BLOB *
} }
/********************************************************* /*********************************************************
Set an extended attribute on a pathname. Set an extended attribute utility fn.
*********************************************************/ *********************************************************/
BOOL cli_set_path_ea(struct cli_state *cli, const char *path, const char *ea_name, const char *ea_val, size_t ea_len) static BOOL cli_set_ea(struct cli_state *cli, uint16 setup, char *param, unsigned int param_len,
const char *ea_name, const char *ea_val, size_t ea_len)
{ {
unsigned int data_len = 0; unsigned int data_len = 0;
unsigned int param_len = 0;
uint16 setup = TRANSACT2_SETPATHINFO;
char param[sizeof(pstring)+6];
char *data = NULL; char *data = NULL;
char *rparam=NULL, *rdata=NULL; char *rparam=NULL, *rdata=NULL;
char *p; char *p;
size_t srclen = 2*(strlen(path)+1);
size_t ea_namelen = strlen(ea_name); size_t ea_namelen = strlen(ea_name);
memset(param, 0, sizeof(param));
SSVAL(param,0,SMB_INFO_SET_EA);
p = &param[6];
p += clistr_push(cli, p, path, MIN(srclen, sizeof(param)-6), STR_TERMINATE);
param_len = PTR_DIFF(p, param);
data_len = 4 + 4 + ea_namelen + 1 + ea_len; data_len = 4 + 4 + ea_namelen + 1 + ea_len;
data = malloc(data_len); data = malloc(data_len);
if (!data) { if (!data) {
@ -1222,82 +1212,65 @@ BOOL cli_set_path_ea(struct cli_state *cli, const char *path, const char *ea_nam
return True; return True;
} }
/*********************************************************
Set an extended attribute on a pathname.
*********************************************************/
BOOL cli_set_ea_path(struct cli_state *cli, const char *path, const char *ea_name, const char *ea_val, size_t ea_len)
{
uint16 setup = TRANSACT2_SETPATHINFO;
unsigned int param_len = 0;
char param[sizeof(pstring)+6];
size_t srclen = 2*(strlen(path)+1);
char *p;
memset(param, 0, sizeof(param));
SSVAL(param,0,SMB_INFO_SET_EA);
p = &param[6];
p += clistr_push(cli, p, path, MIN(srclen, sizeof(param)-6), STR_TERMINATE);
param_len = PTR_DIFF(p, param);
return cli_set_ea(cli, setup, param, param_len, ea_name, ea_val, ea_len);
}
/********************************************************* /*********************************************************
Set an extended attribute on an fnum. 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) BOOL cli_set_ea_fnum(struct cli_state *cli, int fnum, const char *ea_name, const char *ea_val, size_t ea_len)
{ {
unsigned int data_len = 0; char param[6];
unsigned int param_len = 6;
uint16 setup = TRANSACT2_SETFILEINFO; 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)); memset(param, 0, 6);
SSVAL(param,0,fnum); SSVAL(param,0,fnum);
SSVAL(param,2,SMB_INFO_SET_EA); SSVAL(param,2,SMB_INFO_SET_EA);
data_len = 4 + 4 + ea_namelen + 1 + ea_len; return cli_set_ea(cli, setup, param, 6, ea_name, ea_val, 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;
} }
if (!cli_receive_trans(cli, SMBtrans2, /*********************************************************
&rparam, &param_len, Get an extended attribute list tility fn.
&rdata, &data_len)) { *********************************************************/
return False;
}
SAFE_FREE(data); static BOOL cli_get_ea_list(struct cli_state *cli,
SAFE_FREE(rdata); uint16 setup, char *param, unsigned int param_len,
SAFE_FREE(rparam);
return True;
}
BOOL cli_get_eas(struct cli_state *cli, const char *path,
TALLOC_CTX *ctx, TALLOC_CTX *ctx,
size_t *pnum_eas, size_t *pnum_eas,
struct ea_struct **ea_list) struct ea_struct **pea_list)
{ {
unsigned int data_len = 0; unsigned int data_len = 0;
unsigned int param_len = 0;
unsigned int rparam_len, rdata_len; unsigned int rparam_len, rdata_len;
uint16 setup = TRANSACT2_QPATHINFO;
pstring param;
char *rparam=NULL, *rdata=NULL; char *rparam=NULL, *rdata=NULL;
char *p; char *p;
size_t ea_size;
size_t num_eas;
BOOL ret = False;
struct ea_struct *ea_list;
p = param; *pnum_eas = 0;
memset(p, 0, 6); *pea_list = NULL;
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, if (!cli_send_trans(cli, SMBtrans2,
NULL, /* Name */ NULL, /* Name */
@ -1316,7 +1289,123 @@ BOOL cli_get_eas(struct cli_state *cli, const char *path,
} }
if (!rdata || rdata_len < 4) { if (!rdata || rdata_len < 4) {
return False; goto out;
} }
return False;
ea_size = (size_t)IVAL(rdata,0);
if (ea_size > rdata_len) {
goto out;
}
p = rdata + 4;
ea_size -= 4;
/* Validate the EA list and count it. */
for (num_eas = 0; ea_size >= 4; num_eas++) {
unsigned int ea_namelen = CVAL(p,1);
unsigned int ea_valuelen = SVAL(p,2);
if (ea_namelen == 0) {
goto out;
}
if (4 + ea_namelen + 1 + ea_valuelen > ea_size) {
goto out;
}
ea_size -= 4 + ea_namelen + 1 + ea_valuelen;
p += 4 + ea_namelen + 1 + ea_valuelen;
}
if (num_eas == 0) {
ret = True;
goto out;
}
*pnum_eas = num_eas;
if (!pea_list) {
/* Caller only wants number of EA's. */
ret = True;
goto out;
}
ea_list = (struct ea_struct *)talloc(ctx, num_eas*sizeof(struct ea_struct));
if (!ea_list) {
goto out;
}
ea_size = (size_t)IVAL(rdata,0);
p = rdata + 4;
for (num_eas = 0; num_eas < *pnum_eas; num_eas++ ) {
struct ea_struct *ea = &ea_list[num_eas];
fstring unix_ea_name;
unsigned int ea_namelen = CVAL(p,1);
unsigned int ea_valuelen = SVAL(p,2);
ea->flags = CVAL(p,0);
unix_ea_name[0] = '\0';
pull_ascii_fstring(unix_ea_name, p + 4);
ea->name = talloc_strdup(ctx, unix_ea_name);
/* Ensure the value is null terminated (in case it's a string). */
ea->value = data_blob_talloc(ctx, NULL, ea_valuelen + 1);
if (!ea->value.data) {
goto out;
}
if (ea_valuelen) {
memcpy(ea->value.data, p+4+ea_namelen+1, ea_valuelen);
}
ea->value.data[ea_valuelen] = 0;
ea->value.length--;
p += 4 + ea_namelen + 1 + ea_valuelen;
}
*pea_list = ea_list;
ret = True;
out :
SAFE_FREE(rdata);
SAFE_FREE(rparam);
return ret;
}
/*********************************************************
Get an extended attribute list from a pathname.
*********************************************************/
BOOL cli_get_ea_list_path(struct cli_state *cli, const char *path,
TALLOC_CTX *ctx,
size_t *pnum_eas,
struct ea_struct **pea_list)
{
uint16 setup = TRANSACT2_QPATHINFO;
unsigned int param_len = 0;
char param[sizeof(pstring)+6];
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);
return cli_get_ea_list(cli, setup, param, param_len, ctx, pnum_eas, pea_list);
}
/*********************************************************
Get an extended attribute list from an fnum.
*********************************************************/
BOOL cli_get_ea_list_fnum(struct cli_state *cli, int fnum,
TALLOC_CTX *ctx,
size_t *pnum_eas,
struct ea_struct **pea_list)
{
uint16 setup = TRANSACT2_QFILEINFO;
char param[6];
memset(param, 0, 6);
SSVAL(param,0,fnum);
SSVAL(param,2,SMB_INFO_SET_EA);
return cli_get_ea_list(cli, setup, param, 6, ctx, pnum_eas, pea_list);
} }

View File

@ -4316,6 +4316,9 @@ static BOOL run_eatest(int dummy)
const char *fname = "\\eatest.txt"; const char *fname = "\\eatest.txt";
BOOL correct = True; BOOL correct = True;
int fnum, i; int fnum, i;
size_t num_eas;
struct ea_struct *ea_list = NULL;
TALLOC_CTX *mem_ctx = talloc_init("eatest");
printf("starting eatest\n"); printf("starting eatest\n");
@ -4339,7 +4342,7 @@ static BOOL run_eatest(int dummy)
slprintf(ea_name, sizeof(ea_name), "EA_%d", i); slprintf(ea_name, sizeof(ea_name), "EA_%d", i);
memset(ea_val, (char)i+1, i+1); memset(ea_val, (char)i+1, i+1);
if (!cli_set_fnum_ea(cli, fnum, ea_name, ea_val, i+1)) { if (!cli_set_ea_fnum(cli, fnum, ea_name, ea_val, i+1)) {
printf("ea_set of name %s failed - %s\n", ea_name, cli_errstr(cli)); printf("ea_set of name %s failed - %s\n", ea_name, cli_errstr(cli));
return False; return False;
} }
@ -4349,17 +4352,27 @@ static BOOL run_eatest(int dummy)
for (i = 0; i < 10; i++) { for (i = 0; i < 10; i++) {
fstring ea_name, ea_val; fstring ea_name, ea_val;
slprintf(ea_name, sizeof(ea_name), "EA_%d", i); slprintf(ea_name, sizeof(ea_name), "EA_%d", i+10);
memset(ea_val, (char)i+1, i+1); memset(ea_val, (char)i+1, i+1);
if (!cli_set_path_ea(cli, fname, ea_name, ea_val, i+1)) { if (!cli_set_ea_path(cli, fname, ea_name, ea_val, i+1)) {
printf("ea_set of name %s failed - %s\n", ea_name, cli_errstr(cli)); printf("ea_set of name %s failed - %s\n", ea_name, cli_errstr(cli));
return False; return False;
} }
} }
cli_get_eas(cli, fname, NULL,NULL,NULL); if (!cli_get_ea_list_path(cli, fname, mem_ctx, &num_eas, &ea_list)) {
printf("ea_get list failed - %s\n", cli_errstr(cli));
correct = False;
}
printf("num_eas = %d\n", num_eas);
for (i = 0; i < num_eas; i++) {
printf("%d: ea_name = %s. Val = ", i, ea_list[i].name);
dump_data(0, ea_list[i].value.data, ea_list[i].value.length);
}
talloc_destroy(mem_ctx);
if (!torture_close_connection(cli)) { if (!torture_close_connection(cli)) {
correct = False; correct = False;
} }