mirror of
https://github.com/samba-team/samba.git
synced 2025-02-02 09:47:23 +03:00
r4261: added the RAW_FILEINFO_EA_LIST trans2 qfileinfo and qpathinfo
level. Interestingly, this level did now show up on our trans2 scanner previously as we didn't have the FLAGS2_EXTENDED_ATTRIBUTES bit set in the client code. Now that we set that bit, new levels appear in windows servers. (This used to be commit 0b76d405a73e924dc2706f28bbf1084a59c9b393)
This commit is contained in:
parent
daae3bbb29
commit
b706555b3a
@ -313,6 +313,7 @@ enum smb_fileinfo_level {
|
||||
RAW_FILEINFO_SEC_DESC, /* NT_TRANSACT_QUERY_SECURITY_DESC */
|
||||
RAW_FILEINFO_STANDARD = SMB_QFILEINFO_STANDARD,
|
||||
RAW_FILEINFO_EA_SIZE = SMB_QFILEINFO_EA_SIZE,
|
||||
RAW_FILEINFO_EA_LIST = SMB_QFILEINFO_EA_LIST,
|
||||
RAW_FILEINFO_ALL_EAS = SMB_QFILEINFO_ALL_EAS,
|
||||
RAW_FILEINFO_IS_NAME_VALID = SMB_QFILEINFO_IS_NAME_VALID,
|
||||
RAW_FILEINFO_BASIC_INFO = SMB_QFILEINFO_BASIC_INFO,
|
||||
@ -443,16 +444,30 @@ union smb_fileinfo {
|
||||
} out;
|
||||
} ea_size;
|
||||
|
||||
/* trans2 RAW_FILEINFO_EA_LIST interface */
|
||||
struct {
|
||||
enum smb_fileinfo_level level;
|
||||
union smb_fileinfo_in file;
|
||||
|
||||
struct {
|
||||
uint_t num_names;
|
||||
struct ea_name {
|
||||
WIRE_STRING name;
|
||||
} *ea_names;
|
||||
} in;
|
||||
|
||||
struct smb_ea_list {
|
||||
uint_t num_eas;
|
||||
struct ea_struct *eas;
|
||||
} out;
|
||||
} ea_list;
|
||||
|
||||
/* trans2 RAW_FILEINFO_ALL_EAS interface */
|
||||
struct {
|
||||
enum smb_fileinfo_level level;
|
||||
union smb_fileinfo_in in;
|
||||
|
||||
struct smb_ea_list {
|
||||
/* the ea_size is implied by the list */
|
||||
uint_t num_eas;
|
||||
struct ea_struct *eas;
|
||||
} out;
|
||||
struct smb_ea_list out;
|
||||
} all_eas;
|
||||
|
||||
/* trans2 qpathinfo RAW_FILEINFO_IS_NAME_VALID interface
|
||||
|
@ -126,6 +126,7 @@ Found 8 aliased levels
|
||||
*/
|
||||
#define SMB_QFILEINFO_STANDARD 1
|
||||
#define SMB_QFILEINFO_EA_SIZE 2
|
||||
#define SMB_QFILEINFO_EA_LIST 3
|
||||
#define SMB_QFILEINFO_ALL_EAS 4
|
||||
#define SMB_QFILEINFO_IS_NAME_VALID 6 /* only for QPATHINFO */
|
||||
#define SMB_QFILEINFO_BASIC_INFO 0x101
|
||||
|
@ -36,6 +36,19 @@ uint_t ea_list_size(uint_t num_eas, struct ea_struct *eas)
|
||||
return total;
|
||||
}
|
||||
|
||||
/*
|
||||
work out how many bytes on the wire a ea name list will consume.
|
||||
*/
|
||||
static uint_t ea_name_list_size(uint_t num_names, struct ea_name *eas)
|
||||
{
|
||||
uint_t total = 4;
|
||||
int i;
|
||||
for (i=0;i<num_names;i++) {
|
||||
total += 1 + strlen(eas[i].name.s) + 1;
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
||||
/*
|
||||
work out how many bytes on the wire a chained ea list will consume.
|
||||
This assumes the names are strict ascii, which should be a
|
||||
@ -242,4 +255,107 @@ NTSTATUS ea_pull_list_chained(const DATA_BLOB *blob,
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
pull a ea_name from a buffer. Return the number of bytes consumed
|
||||
*/
|
||||
static uint_t ea_pull_name(const DATA_BLOB *blob,
|
||||
TALLOC_CTX *mem_ctx,
|
||||
struct ea_name *ea)
|
||||
{
|
||||
uint8_t nlen;
|
||||
|
||||
if (blob->length < 2) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
nlen = CVAL(blob->data, 0);
|
||||
|
||||
if (nlen+2 > blob->length) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
ea->name.s = talloc_strndup(mem_ctx, (const char *)(blob->data+1), nlen);
|
||||
ea->name.private_length = nlen;
|
||||
|
||||
return nlen+2;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
pull a ea_name list from a buffer
|
||||
*/
|
||||
NTSTATUS ea_pull_name_list(const DATA_BLOB *blob,
|
||||
TALLOC_CTX *mem_ctx,
|
||||
uint_t *num_names, struct ea_name **ea_names)
|
||||
{
|
||||
int n;
|
||||
uint32_t ea_size, ofs;
|
||||
|
||||
if (blob->length < 4) {
|
||||
return NT_STATUS_INFO_LENGTH_MISMATCH;
|
||||
}
|
||||
|
||||
ea_size = IVAL(blob->data, 0);
|
||||
if (ea_size > blob->length) {
|
||||
return NT_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
ofs = 4;
|
||||
n = 0;
|
||||
*num_names = 0;
|
||||
*ea_names = NULL;
|
||||
|
||||
while (ofs < ea_size) {
|
||||
uint_t len;
|
||||
DATA_BLOB blob2;
|
||||
|
||||
blob2.data = blob->data + ofs;
|
||||
blob2.length = ea_size - ofs;
|
||||
|
||||
*ea_names = talloc_realloc_p(mem_ctx, *ea_names, struct ea_name, n+1);
|
||||
if (! *ea_names) return NT_STATUS_NO_MEMORY;
|
||||
|
||||
len = ea_pull_name(&blob2, mem_ctx, &(*ea_names)[n]);
|
||||
if (len == 0) {
|
||||
return NT_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
ofs += len;
|
||||
n++;
|
||||
}
|
||||
|
||||
*num_names = n;
|
||||
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
put a ea_name list into a data blob
|
||||
*/
|
||||
BOOL ea_push_name_list(TALLOC_CTX *mem_ctx,
|
||||
DATA_BLOB *data, uint_t num_names, struct ea_name *eas)
|
||||
{
|
||||
int i;
|
||||
uint32_t ea_size;
|
||||
uint32_t off;
|
||||
|
||||
ea_size = ea_name_list_size(num_names, eas);
|
||||
|
||||
*data = data_blob_talloc(mem_ctx, NULL, ea_size);
|
||||
if (data->data == NULL) {
|
||||
return False;
|
||||
}
|
||||
|
||||
SIVAL(data->data, 0, ea_size);
|
||||
off = 4;
|
||||
|
||||
for (i=0;i<num_names;i++) {
|
||||
uint_t nlen = strlen(eas[i].name.s);
|
||||
SCVAL(data->data, off, nlen);
|
||||
memcpy(data->data+off+1, eas[i].name.s, nlen+1);
|
||||
off += 1+nlen+1;
|
||||
}
|
||||
|
||||
return True;
|
||||
}
|
||||
|
@ -79,6 +79,12 @@ static NTSTATUS smb_raw_info_backend(struct smbcli_session *session,
|
||||
parms->ea_size.out.ea_size = IVAL(blob->data, 22);
|
||||
return NT_STATUS_OK;
|
||||
|
||||
case RAW_FILEINFO_EA_LIST:
|
||||
FINFO_CHECK_MIN_SIZE(4);
|
||||
return ea_pull_list(blob, mem_ctx,
|
||||
&parms->ea_list.out.num_eas,
|
||||
&parms->ea_list.out.eas);
|
||||
|
||||
case RAW_FILEINFO_ALL_EAS:
|
||||
FINFO_CHECK_MIN_SIZE(4);
|
||||
return ea_pull_list(blob, mem_ctx,
|
||||
@ -280,7 +286,9 @@ static NTSTATUS smb_raw_info_backend(struct smbcli_session *session,
|
||||
Very raw query file info - returns param/data blobs - (async send)
|
||||
****************************************************************************/
|
||||
static struct smbcli_request *smb_raw_fileinfo_blob_send(struct smbcli_tree *tree,
|
||||
uint16_t fnum, uint16_t info_level)
|
||||
uint16_t fnum,
|
||||
uint16_t info_level,
|
||||
DATA_BLOB data)
|
||||
{
|
||||
struct smb_trans2 tp;
|
||||
uint16_t setup = TRANSACT2_QFILEINFO;
|
||||
@ -291,7 +299,7 @@ static struct smbcli_request *smb_raw_fileinfo_blob_send(struct smbcli_tree *tre
|
||||
tp.in.flags = 0;
|
||||
tp.in.timeout = 0;
|
||||
tp.in.setup_count = 1;
|
||||
tp.in.data = data_blob(NULL, 0);
|
||||
tp.in.data = data;
|
||||
tp.in.max_param = 2;
|
||||
tp.in.max_data = smb_raw_max_trans_data(tree, 2);
|
||||
tp.in.setup = &setup;
|
||||
@ -332,8 +340,9 @@ static NTSTATUS smb_raw_fileinfo_blob_recv(struct smbcli_request *req,
|
||||
Very raw query path info - returns param/data blobs (async send)
|
||||
****************************************************************************/
|
||||
static struct smbcli_request *smb_raw_pathinfo_blob_send(struct smbcli_tree *tree,
|
||||
const char *fname,
|
||||
uint16_t info_level)
|
||||
const char *fname,
|
||||
uint16_t info_level,
|
||||
DATA_BLOB data)
|
||||
{
|
||||
struct smb_trans2 tp;
|
||||
uint16_t setup = TRANSACT2_QPATHINFO;
|
||||
@ -344,7 +353,7 @@ static struct smbcli_request *smb_raw_pathinfo_blob_send(struct smbcli_tree *tre
|
||||
tp.in.flags = 0;
|
||||
tp.in.timeout = 0;
|
||||
tp.in.setup_count = 1;
|
||||
tp.in.data = data_blob(NULL, 0);
|
||||
tp.in.data = data;
|
||||
tp.in.max_param = 2;
|
||||
tp.in.max_data = smb_raw_max_trans_data(tree, 2);
|
||||
tp.in.setup = &setup;
|
||||
@ -463,6 +472,9 @@ failed:
|
||||
struct smbcli_request *smb_raw_fileinfo_send(struct smbcli_tree *tree,
|
||||
union smb_fileinfo *parms)
|
||||
{
|
||||
DATA_BLOB data;
|
||||
struct smbcli_request *req;
|
||||
|
||||
/* pass off the non-trans2 level to specialised functions */
|
||||
if (parms->generic.level == RAW_FILEINFO_GETATTRE) {
|
||||
return smb_raw_getattrE_send(tree, parms);
|
||||
@ -474,9 +486,24 @@ struct smbcli_request *smb_raw_fileinfo_send(struct smbcli_tree *tree,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return smb_raw_fileinfo_blob_send(tree,
|
||||
parms->generic.in.fnum,
|
||||
parms->generic.level);
|
||||
data = data_blob(NULL, 0);
|
||||
|
||||
if (parms->generic.level == RAW_FILEINFO_EA_LIST) {
|
||||
if (!ea_push_name_list(tree,
|
||||
&data,
|
||||
parms->ea_list.in.num_names,
|
||||
parms->ea_list.in.ea_names)) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
req = smb_raw_fileinfo_blob_send(tree,
|
||||
parms->generic.in.fnum,
|
||||
parms->generic.level, data);
|
||||
|
||||
data_blob_free(&data);
|
||||
|
||||
return req;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@ -525,6 +552,9 @@ NTSTATUS smb_raw_fileinfo(struct smbcli_tree *tree,
|
||||
struct smbcli_request *smb_raw_pathinfo_send(struct smbcli_tree *tree,
|
||||
union smb_fileinfo *parms)
|
||||
{
|
||||
DATA_BLOB data;
|
||||
struct smbcli_request *req;
|
||||
|
||||
if (parms->generic.level == RAW_FILEINFO_GETATTR) {
|
||||
return smb_raw_getattr_send(tree, parms);
|
||||
}
|
||||
@ -532,8 +562,22 @@ struct smbcli_request *smb_raw_pathinfo_send(struct smbcli_tree *tree,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return smb_raw_pathinfo_blob_send(tree, parms->generic.in.fname,
|
||||
parms->generic.level);
|
||||
data = data_blob(NULL, 0);
|
||||
|
||||
if (parms->generic.level == RAW_FILEINFO_EA_LIST) {
|
||||
if (!ea_push_name_list(tree,
|
||||
&data,
|
||||
parms->ea_list.in.num_names,
|
||||
parms->ea_list.in.ea_names)) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
req = smb_raw_pathinfo_blob_send(tree, parms->generic.in.fname,
|
||||
parms->generic.level, data);
|
||||
data_blob_free(&data);
|
||||
|
||||
return req;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -24,6 +24,45 @@
|
||||
#include "vfs_posix.h"
|
||||
#include "librpc/gen_ndr/ndr_xattr.h"
|
||||
|
||||
/*
|
||||
reply to a RAW_FILEINFO_EA_LIST call
|
||||
*/
|
||||
static NTSTATUS pvfs_query_ea_list(struct pvfs_state *pvfs, TALLOC_CTX *mem_ctx,
|
||||
struct pvfs_filename *name, int fd,
|
||||
uint_t num_names,
|
||||
struct ea_name *names,
|
||||
struct smb_ea_list *eas)
|
||||
{
|
||||
NTSTATUS status;
|
||||
int i;
|
||||
struct xattr_DosEAs *ealist = talloc_p(mem_ctx, struct xattr_DosEAs);
|
||||
|
||||
ZERO_STRUCTP(eas);
|
||||
status = pvfs_doseas_load(pvfs, name, fd, ealist);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
return status;
|
||||
}
|
||||
eas->eas = talloc_array_p(mem_ctx, struct ea_struct, num_names);
|
||||
if (eas->eas == NULL) {
|
||||
return NT_STATUS_NO_MEMORY;
|
||||
}
|
||||
eas->num_eas = num_names;
|
||||
for (i=0;i<num_names;i++) {
|
||||
int j;
|
||||
eas->eas[i].flags = 0;
|
||||
eas->eas[i].name.s = names[i].name.s;
|
||||
eas->eas[i].value = data_blob(NULL, 0);
|
||||
for (j=0;j<ealist->num_eas;j++) {
|
||||
if (StrCaseCmp(eas->eas[i].name.s,
|
||||
ealist->eas[j].name) == 0) {
|
||||
eas->eas[i].value = ealist->eas[j].value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
reply to a RAW_FILEINFO_ALL_EAS call
|
||||
*/
|
||||
@ -40,15 +79,16 @@ static NTSTATUS pvfs_query_all_eas(struct pvfs_state *pvfs, TALLOC_CTX *mem_ctx,
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
return status;
|
||||
}
|
||||
eas->num_eas = ealist->num_eas;
|
||||
eas->eas = talloc_array_p(mem_ctx, struct ea_struct, eas->num_eas);
|
||||
eas->eas = talloc_array_p(mem_ctx, struct ea_struct, ealist->num_eas);
|
||||
if (eas->eas == NULL) {
|
||||
return NT_STATUS_NO_MEMORY;
|
||||
}
|
||||
for (i=0;i<eas->num_eas;i++) {
|
||||
eas->eas[i].flags = 0;
|
||||
eas->eas[i].name.s = ealist->eas[i].name;
|
||||
eas->eas[i].value = ealist->eas[i].value;
|
||||
eas->num_eas = 0;
|
||||
for (i=0;i<ealist->num_eas;i++) {
|
||||
eas->eas[eas->num_eas].flags = 0;
|
||||
eas->eas[eas->num_eas].name.s = ealist->eas[i].name;
|
||||
eas->eas[eas->num_eas].value = ealist->eas[i].value;
|
||||
eas->num_eas++;
|
||||
}
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
@ -91,6 +131,12 @@ static NTSTATUS pvfs_map_fileinfo(struct pvfs_state *pvfs,
|
||||
info->ea_size.out.ea_size = name->dos.ea_size;
|
||||
return NT_STATUS_OK;
|
||||
|
||||
case RAW_FILEINFO_EA_LIST:
|
||||
return pvfs_query_ea_list(pvfs, req, name, fd,
|
||||
info->ea_list.in.num_names,
|
||||
info->ea_list.in.ea_names,
|
||||
&info->ea_list.out);
|
||||
|
||||
case RAW_FILEINFO_ALL_EAS:
|
||||
return pvfs_query_all_eas(pvfs, req, name, fd, &info->all_eas.out);
|
||||
|
||||
|
@ -614,6 +614,15 @@ static NTSTATUS trans2_fileinfo_fill(struct smbsrv_request *req, struct smb_tran
|
||||
st->alignment_information.out.alignment_requirement);
|
||||
return NT_STATUS_OK;
|
||||
|
||||
case RAW_FILEINFO_EA_LIST:
|
||||
list_size = ea_list_size(st->ea_list.out.num_eas,
|
||||
st->ea_list.out.eas);
|
||||
trans2_setup_reply(req, trans, 2, list_size, 0);
|
||||
SSVAL(trans->out.params.data, 0, 0);
|
||||
ea_put_list(trans->out.data.data,
|
||||
st->ea_list.out.num_eas, st->ea_list.out.eas);
|
||||
return NT_STATUS_OK;
|
||||
|
||||
case RAW_FILEINFO_ALL_EAS:
|
||||
list_size = ea_list_size(st->all_eas.out.num_eas,
|
||||
st->all_eas.out.eas);
|
||||
@ -753,6 +762,15 @@ static NTSTATUS trans2_qpathinfo(struct smbsrv_request *req, struct smb_trans2 *
|
||||
return NT_STATUS_INVALID_LEVEL;
|
||||
}
|
||||
|
||||
if (st.generic.level == RAW_FILEINFO_EA_LIST) {
|
||||
status = ea_pull_name_list(&trans->in.data, req,
|
||||
&st.ea_list.in.num_names,
|
||||
&st.ea_list.in.ea_names);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
return status;
|
||||
}
|
||||
}
|
||||
|
||||
/* call the backend */
|
||||
status = ntvfs_qpathinfo(req, &st);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
@ -789,6 +807,15 @@ static NTSTATUS trans2_qfileinfo(struct smbsrv_request *req, struct smb_trans2 *
|
||||
return NT_STATUS_INVALID_LEVEL;
|
||||
}
|
||||
|
||||
if (st.generic.level == RAW_FILEINFO_EA_LIST) {
|
||||
status = ea_pull_name_list(&trans->in.data, req,
|
||||
&st.ea_list.in.num_names,
|
||||
&st.ea_list.in.ea_names);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
return status;
|
||||
}
|
||||
}
|
||||
|
||||
/* call the backend */
|
||||
status = ntvfs_qfileinfo(req, &st);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
|
@ -362,11 +362,15 @@ NTSTATUS torture_check_ea(struct smbcli_state *cli,
|
||||
{
|
||||
union smb_fileinfo info;
|
||||
NTSTATUS status;
|
||||
int i;
|
||||
struct ea_name ea;
|
||||
TALLOC_CTX *mem_ctx = talloc(cli, 0);
|
||||
|
||||
info.all_eas.level = RAW_FILEINFO_ALL_EAS;
|
||||
info.all_eas.in.fname = fname;
|
||||
info.ea_list.level = RAW_FILEINFO_EA_LIST;
|
||||
info.ea_list.file.fname = fname;
|
||||
info.ea_list.in.num_names = 1;
|
||||
info.ea_list.in.ea_names = &ea;
|
||||
|
||||
ea.name.s = eaname;
|
||||
|
||||
status = smb_raw_pathinfo(cli->tree, mem_ctx, &info);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
@ -374,38 +378,45 @@ NTSTATUS torture_check_ea(struct smbcli_state *cli,
|
||||
return status;
|
||||
}
|
||||
|
||||
for (i=0;i<info.all_eas.out.num_eas;i++) {
|
||||
if (StrCaseCmp(eaname, info.all_eas.out.eas[i].name.s) == 0) {
|
||||
if (value == NULL) {
|
||||
printf("attr '%s' should not be present\n", eaname);
|
||||
talloc_free(mem_ctx);
|
||||
return NT_STATUS_EA_CORRUPT_ERROR;
|
||||
}
|
||||
if (strlen(value) == info.all_eas.out.eas[i].value.length &&
|
||||
memcmp(value,
|
||||
info.all_eas.out.eas[i].value.data,
|
||||
info.all_eas.out.eas[i].value.length) == 0) {
|
||||
talloc_free(mem_ctx);
|
||||
return NT_STATUS_OK;
|
||||
} else {
|
||||
printf("attr '%s' has wrong value '%*.*s'\n",
|
||||
eaname,
|
||||
info.all_eas.out.eas[i].value.length,
|
||||
info.all_eas.out.eas[i].value.length,
|
||||
info.all_eas.out.eas[i].value.data);
|
||||
talloc_free(mem_ctx);
|
||||
return NT_STATUS_EA_CORRUPT_ERROR;
|
||||
}
|
||||
}
|
||||
if (info.ea_list.out.num_eas != 1) {
|
||||
printf("Expected 1 ea in ea_list\n");
|
||||
talloc_free(mem_ctx);
|
||||
return NT_STATUS_EA_CORRUPT_ERROR;
|
||||
}
|
||||
|
||||
if (StrCaseCmp(eaname, info.ea_list.out.eas[0].name.s) != 0) {
|
||||
printf("Expected ea '%s' not '%s' in ea_list\n",
|
||||
eaname, info.ea_list.out.eas[0].name.s);
|
||||
talloc_free(mem_ctx);
|
||||
return NT_STATUS_EA_CORRUPT_ERROR;
|
||||
}
|
||||
|
||||
if (value == NULL) {
|
||||
if (info.ea_list.out.eas[0].value.length != 0) {
|
||||
printf("Expected zero length ea for %s\n", eaname);
|
||||
talloc_free(mem_ctx);
|
||||
return NT_STATUS_EA_CORRUPT_ERROR;
|
||||
}
|
||||
talloc_free(mem_ctx);
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
if (strlen(value) == info.ea_list.out.eas[0].value.length &&
|
||||
memcmp(value, info.ea_list.out.eas[0].value.data,
|
||||
info.ea_list.out.eas[0].value.length) == 0) {
|
||||
talloc_free(mem_ctx);
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
printf("Expected value '%s' not '%*.*s' for ea %s\n",
|
||||
value,
|
||||
info.ea_list.out.eas[0].value.length,
|
||||
info.ea_list.out.eas[0].value.length,
|
||||
info.ea_list.out.eas[0].value.data,
|
||||
eaname);
|
||||
|
||||
talloc_free(mem_ctx);
|
||||
|
||||
if (value != NULL) {
|
||||
printf("attr '%s' not found\n", eaname);
|
||||
return NT_STATUS_NONEXISTENT_EA_ENTRY;
|
||||
}
|
||||
|
||||
return NT_STATUS_OK;
|
||||
return NT_STATUS_EA_CORRUPT_ERROR;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user