netapi32: Add support for info level 502 in NetShareAdd.
This commit is contained in:
parent
499eed087e
commit
d9723d2bed
|
@ -298,11 +298,474 @@ static NET_API_STATUS share_info_2_to_samba( const BYTE *buf, unsigned char **bu
|
|||
return NERR_Success;
|
||||
}
|
||||
|
||||
struct sid
|
||||
{
|
||||
unsigned char sid_rev_num;
|
||||
unsigned char num_auths;
|
||||
unsigned char id_auth[6];
|
||||
unsigned int sub_auths[15];
|
||||
};
|
||||
|
||||
enum ace_type
|
||||
{
|
||||
ACE_TYPE_ACCESS_ALLOWED,
|
||||
ACE_TYPE_ACCESS_DENIED,
|
||||
ACE_TYPE_SYSTEM_AUDIT,
|
||||
ACE_TYPE_SYSTEM_ALARM,
|
||||
ACE_TYPE_ALLOWED_COMPOUND,
|
||||
ACE_TYPE_ACCESS_ALLOWED_OBJECT,
|
||||
ACE_TYPE_ACCESS_DENIED_OBJECT,
|
||||
ACE_TYPE_SYSTEM_AUDIT_OBJECT,
|
||||
ACE_TYPE_SYSTEM_ALARM_OBJECT
|
||||
};
|
||||
|
||||
#define SEC_ACE_FLAG_OBJECT_INHERIT 0x01
|
||||
#define SEC_ACE_FLAG_CONTAINER_INHERIT 0x02
|
||||
#define SEC_ACE_FLAG_NO_PROPAGATE_INHERIT 0x04
|
||||
#define SEC_ACE_FLAG_INHERIT_ONLY 0x08
|
||||
#define SEC_ACE_FLAG_INHERITED_ACE 0x10
|
||||
#define SEC_ACE_FLAG_SUCCESSFUL_ACCESS 0x40
|
||||
#define SEC_ACE_FLAG_FAILED_ACCESS 0x80
|
||||
|
||||
struct guid
|
||||
{
|
||||
unsigned int time_low;
|
||||
unsigned short time_mid;
|
||||
unsigned short time_hi_and_version;
|
||||
unsigned char clock_seq[2];
|
||||
unsigned char node[6];
|
||||
};
|
||||
|
||||
union ace_object_type
|
||||
{
|
||||
struct guid type;
|
||||
};
|
||||
|
||||
union ace_object_inherited_type
|
||||
{
|
||||
struct guid inherited_type;
|
||||
};
|
||||
|
||||
struct ace_object
|
||||
{
|
||||
unsigned int flags;
|
||||
union ace_object_type type;
|
||||
union ace_object_inherited_type inherited_type;
|
||||
};
|
||||
|
||||
union ace_object_ctr
|
||||
{
|
||||
struct ace_object object;
|
||||
};
|
||||
|
||||
struct ace
|
||||
{
|
||||
enum ace_type type;
|
||||
unsigned char flags;
|
||||
unsigned short size;
|
||||
unsigned int access_mask;
|
||||
union ace_object_ctr object;
|
||||
struct sid trustee;
|
||||
};
|
||||
|
||||
enum acl_revision
|
||||
{
|
||||
ACL_REVISION_NT4 = 2,
|
||||
ACL_REVISION_ADS = 4
|
||||
};
|
||||
|
||||
struct acl
|
||||
{
|
||||
enum acl_revision revision;
|
||||
unsigned short size;
|
||||
unsigned int num_aces;
|
||||
struct ace *aces;
|
||||
};
|
||||
|
||||
enum security_descriptor_revision
|
||||
{
|
||||
SECURITY_DESCRIPTOR_REVISION_1 = 1
|
||||
};
|
||||
|
||||
#define SEC_DESC_OWNER_DEFAULTED 0x0001
|
||||
#define SEC_DESC_GROUP_DEFAULTED 0x0002
|
||||
#define SEC_DESC_DACL_PRESENT 0x0004
|
||||
#define SEC_DESC_DACL_DEFAULTED 0x0008
|
||||
#define SEC_DESC_SACL_PRESENT 0x0010
|
||||
#define SEC_DESC_SACL_DEFAULTED 0x0020
|
||||
#define SEC_DESC_DACL_TRUSTED 0x0040
|
||||
#define SEC_DESC_SERVER_SECURITY 0x0080
|
||||
#define SEC_DESC_DACL_AUTO_INHERIT_REQ 0x0100
|
||||
#define SEC_DESC_SACL_AUTO_INHERIT_REQ 0x0200
|
||||
#define SEC_DESC_DACL_AUTO_INHERITED 0x0400
|
||||
#define SEC_DESC_SACL_AUTO_INHERITED 0x0800
|
||||
#define SEC_DESC_DACL_PROTECTED 0x1000
|
||||
#define SEC_DESC_SACL_PROTECTED 0x2000
|
||||
#define SEC_DESC_RM_CONTROL_VALID 0x4000
|
||||
#define SEC_DESC_SELF_RELATIVE 0x8000
|
||||
|
||||
struct security_descriptor
|
||||
{
|
||||
enum security_descriptor_revision revision;
|
||||
unsigned short type;
|
||||
struct sid *owner_sid;
|
||||
struct sid *group_sid;
|
||||
struct acl *sacl;
|
||||
struct acl *dacl;
|
||||
};
|
||||
|
||||
struct share_info_502
|
||||
{
|
||||
const char *shi502_netname;
|
||||
unsigned int shi502_type;
|
||||
const char *shi502_remark;
|
||||
unsigned int shi502_permissions;
|
||||
unsigned int shi502_max_uses;
|
||||
unsigned int shi502_current_uses;
|
||||
const char *shi502_path;
|
||||
const char *shi502_passwd;
|
||||
unsigned int shi502_reserved;
|
||||
struct security_descriptor *shi502_security_descriptor;
|
||||
};
|
||||
|
||||
static unsigned short sd_control_to_samba( SECURITY_DESCRIPTOR_CONTROL control )
|
||||
{
|
||||
unsigned short ret = 0;
|
||||
|
||||
if (control & SE_OWNER_DEFAULTED) ret |= SEC_DESC_OWNER_DEFAULTED;
|
||||
if (control & SE_GROUP_DEFAULTED) ret |= SEC_DESC_GROUP_DEFAULTED;
|
||||
if (control & SE_DACL_PRESENT) ret |= SEC_DESC_DACL_PRESENT;
|
||||
if (control & SE_DACL_DEFAULTED) ret |= SEC_DESC_DACL_DEFAULTED;
|
||||
if (control & SE_SACL_PRESENT) ret |= SEC_DESC_SACL_PRESENT;
|
||||
if (control & SE_SACL_DEFAULTED) ret |= SEC_DESC_SACL_DEFAULTED;
|
||||
if (control & SE_DACL_AUTO_INHERIT_REQ) ret |= SEC_DESC_DACL_AUTO_INHERIT_REQ;
|
||||
if (control & SE_SACL_AUTO_INHERIT_REQ) ret |= SEC_DESC_SACL_AUTO_INHERIT_REQ;
|
||||
if (control & SE_DACL_AUTO_INHERITED) ret |= SEC_DESC_DACL_AUTO_INHERITED;
|
||||
if (control & SE_SACL_AUTO_INHERITED) ret |= SEC_DESC_SACL_AUTO_INHERITED;
|
||||
if (control & SE_DACL_PROTECTED) ret |= SEC_DESC_DACL_PROTECTED;
|
||||
if (control & SE_SACL_PROTECTED) ret |= SEC_DESC_SACL_PROTECTED;
|
||||
if (control & SE_RM_CONTROL_VALID) ret |= SEC_DESC_RM_CONTROL_VALID;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static NET_API_STATUS sid_to_samba( const SID *src, struct sid *dst )
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
if (src->Revision != 1)
|
||||
{
|
||||
ERR( "unknown revision %u\n", src->Revision );
|
||||
return ERROR_UNKNOWN_REVISION;
|
||||
}
|
||||
if (src->SubAuthorityCount > SID_MAX_SUB_AUTHORITIES)
|
||||
{
|
||||
WARN( "invalid subauthority count %u\n", src->SubAuthorityCount );
|
||||
return ERROR_INVALID_PARAMETER;
|
||||
}
|
||||
dst->sid_rev_num = SECURITY_DESCRIPTOR_REVISION_1;
|
||||
dst->num_auths = src->SubAuthorityCount;
|
||||
for (i = 0; i < 6; i++) dst->id_auth[i] = src->IdentifierAuthority.Value[i];
|
||||
for (i = 0; i < dst->num_auths; i++) dst->sub_auths[i] = src->SubAuthority[i];
|
||||
return NERR_Success;
|
||||
}
|
||||
|
||||
static enum ace_type ace_type_to_samba( BYTE type )
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case ACCESS_ALLOWED_ACE_TYPE: return ACE_TYPE_ACCESS_ALLOWED;
|
||||
case ACCESS_DENIED_ACE_TYPE: return ACE_TYPE_ACCESS_DENIED;
|
||||
case SYSTEM_AUDIT_ACE_TYPE: return ACE_TYPE_SYSTEM_AUDIT;
|
||||
case SYSTEM_ALARM_ACE_TYPE: return ACE_TYPE_SYSTEM_ALARM;
|
||||
default:
|
||||
ERR( "unhandled type %u\n", type );
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static unsigned char ace_flags_to_samba( BYTE flags )
|
||||
{
|
||||
static const BYTE known_flags =
|
||||
OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE | NO_PROPAGATE_INHERIT_ACE |
|
||||
INHERIT_ONLY_ACE | INHERITED_ACE | SUCCESSFUL_ACCESS_ACE_FLAG | FAILED_ACCESS_ACE_FLAG;
|
||||
unsigned char ret = 0;
|
||||
|
||||
if (flags & ~known_flags)
|
||||
{
|
||||
ERR( "unknown flags %x\n", flags & ~known_flags );
|
||||
return 0;
|
||||
}
|
||||
if (flags & OBJECT_INHERIT_ACE) ret |= SEC_ACE_FLAG_OBJECT_INHERIT;
|
||||
if (flags & CONTAINER_INHERIT_ACE) ret |= SEC_ACE_FLAG_NO_PROPAGATE_INHERIT;
|
||||
if (flags & NO_PROPAGATE_INHERIT_ACE) ret |= SEC_ACE_FLAG_NO_PROPAGATE_INHERIT;
|
||||
if (flags & INHERIT_ONLY_ACE) ret |= SEC_ACE_FLAG_INHERIT_ONLY;
|
||||
if (flags & INHERITED_ACE) ret |= SEC_ACE_FLAG_INHERITED_ACE;
|
||||
if (flags & SUCCESSFUL_ACCESS_ACE_FLAG) ret |= SEC_ACE_FLAG_SUCCESSFUL_ACCESS;
|
||||
if (flags & FAILED_ACCESS_ACE_FLAG) ret |= SEC_ACE_FLAG_FAILED_ACCESS;
|
||||
return ret;
|
||||
}
|
||||
|
||||
#define GENERIC_ALL_ACCESS (1 << 28)
|
||||
#define GENERIC_EXECUTE_ACCESS (1 << 29)
|
||||
#define GENERIC_WRITE_ACCESS (1 << 30)
|
||||
#define GENERIC_READ_ACCESS (1 << 31)
|
||||
|
||||
unsigned int access_mask_to_samba( DWORD mask )
|
||||
{
|
||||
static const DWORD known_rights =
|
||||
GENERIC_ALL | GENERIC_EXECUTE | GENERIC_WRITE | GENERIC_READ;
|
||||
unsigned int ret = 0;
|
||||
|
||||
if (mask & ~known_rights)
|
||||
{
|
||||
ERR( "unknown rights %x\n", mask & ~known_rights );
|
||||
return 0;
|
||||
}
|
||||
if (mask & GENERIC_ALL) ret |= GENERIC_ALL_ACCESS;
|
||||
if (mask & GENERIC_EXECUTE) ret |= GENERIC_EXECUTE_ACCESS;
|
||||
if (mask & GENERIC_WRITE) ret |= GENERIC_WRITE_ACCESS;
|
||||
if (mask & GENERIC_READ) ret |= GENERIC_READ_ACCESS;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static NET_API_STATUS ace_to_samba( const ACE_HEADER *src, struct ace *dst )
|
||||
{
|
||||
dst->type = ace_type_to_samba( src->AceType );
|
||||
dst->flags = ace_flags_to_samba( src->AceFlags );
|
||||
dst->size = sizeof(*dst);
|
||||
switch (src->AceType)
|
||||
{
|
||||
case ACCESS_ALLOWED_ACE_TYPE:
|
||||
{
|
||||
ACCESS_ALLOWED_ACE *ace = (ACCESS_ALLOWED_ACE *)src;
|
||||
dst->access_mask = access_mask_to_samba( ace->Mask );
|
||||
memset( &dst->object, 0, sizeof(dst->object) );
|
||||
sid_to_samba( (const SID *)&ace->SidStart, &dst->trustee );
|
||||
}
|
||||
case ACCESS_DENIED_ACE_TYPE:
|
||||
{
|
||||
ACCESS_DENIED_ACE *ace = (ACCESS_DENIED_ACE *)src;
|
||||
dst->access_mask = access_mask_to_samba( ace->Mask );
|
||||
memset( &dst->object, 0, sizeof(dst->object) );
|
||||
sid_to_samba( (const SID *)&ace->SidStart, &dst->trustee );
|
||||
}
|
||||
case SYSTEM_AUDIT_ACE_TYPE:
|
||||
{
|
||||
SYSTEM_AUDIT_ACE *ace = (SYSTEM_AUDIT_ACE *)src;
|
||||
dst->access_mask = access_mask_to_samba( ace->Mask );
|
||||
memset( &dst->object, 0, sizeof(dst->object) );
|
||||
sid_to_samba( (const SID *)&ace->SidStart, &dst->trustee );
|
||||
}
|
||||
case SYSTEM_ALARM_ACE_TYPE:
|
||||
{
|
||||
SYSTEM_ALARM_ACE *ace = (SYSTEM_ALARM_ACE *)src;
|
||||
dst->access_mask = access_mask_to_samba( ace->Mask );
|
||||
memset( &dst->object, 0, sizeof(dst->object) );
|
||||
sid_to_samba( (const SID *)&ace->SidStart, &dst->trustee );
|
||||
}
|
||||
default:
|
||||
ERR( "unhandled type %u\n", src->AceType );
|
||||
return ERROR_INVALID_PARAMETER;
|
||||
}
|
||||
return NERR_Success;
|
||||
}
|
||||
|
||||
static NET_API_STATUS acl_to_samba( const ACL *src, struct acl *dst )
|
||||
{
|
||||
NET_API_STATUS status;
|
||||
ACE_HEADER *src_ace;
|
||||
unsigned int i;
|
||||
|
||||
switch (src->AclRevision)
|
||||
{
|
||||
case ACL_REVISION4:
|
||||
dst->revision = ACL_REVISION_ADS;
|
||||
break;
|
||||
default:
|
||||
ERR( "unkhandled revision %u\n", src->AclRevision );
|
||||
return ERROR_UNKNOWN_REVISION;
|
||||
}
|
||||
dst->size = sizeof(*dst);
|
||||
src_ace = (ACE_HEADER *)(src + 1);
|
||||
dst->aces = (struct ace *)(dst + 1);
|
||||
for (i = 0; i < src->AceCount; i++)
|
||||
{
|
||||
if ((status = ace_to_samba( src_ace, &dst->aces[i] ))) return status;
|
||||
src_ace = (ACE_HEADER *)((char *)src_ace + src_ace->AceSize);
|
||||
dst->size += dst->aces[i].size;
|
||||
}
|
||||
return NERR_Success;
|
||||
}
|
||||
|
||||
#define SELF_RELATIVE_FIELD(sd,field)\
|
||||
((char *)(sd) + ((SECURITY_DESCRIPTOR_RELATIVE *)(sd))->field)
|
||||
|
||||
static NET_API_STATUS sd_to_samba( const SECURITY_DESCRIPTOR *src, struct security_descriptor *dst )
|
||||
{
|
||||
NET_API_STATUS status;
|
||||
const SID *owner, *group;
|
||||
const ACL *dacl, *sacl;
|
||||
unsigned int offset = sizeof(*dst);
|
||||
|
||||
if (src->Revision != SECURITY_DESCRIPTOR_REVISION1)
|
||||
return ERROR_UNKNOWN_REVISION;
|
||||
|
||||
dst->revision = SECURITY_DESCRIPTOR_REVISION_1;
|
||||
dst->type = sd_control_to_samba( src->Control );
|
||||
|
||||
if (src->Control & SE_SELF_RELATIVE)
|
||||
{
|
||||
if (!src->Owner) dst->owner_sid = NULL;
|
||||
else
|
||||
{
|
||||
dst->owner_sid = (struct sid *)((char *)dst + offset);
|
||||
owner = (const SID *)SELF_RELATIVE_FIELD( src, Owner );
|
||||
if ((status = sid_to_samba( owner, dst->owner_sid ))) return status;
|
||||
offset += sizeof(struct sid);
|
||||
}
|
||||
if (!src->Group) dst->group_sid = NULL;
|
||||
else
|
||||
{
|
||||
dst->group_sid = (struct sid *)((char *)dst + offset);
|
||||
group = (const SID *)SELF_RELATIVE_FIELD( src, Group );
|
||||
if ((status = sid_to_samba( group, dst->group_sid ))) return status;
|
||||
offset += sizeof(struct sid);
|
||||
}
|
||||
if (!(src->Control & SE_SACL_PRESENT)) dst->sacl = NULL;
|
||||
else
|
||||
{
|
||||
dst->sacl = (struct acl *)((char *)dst + offset);
|
||||
sacl = (const ACL *)SELF_RELATIVE_FIELD( src, Sacl );
|
||||
if ((status = acl_to_samba( sacl, dst->sacl ))) return status;
|
||||
offset += dst->sacl->size;
|
||||
}
|
||||
if (!(src->Control & SE_DACL_PRESENT)) dst->dacl = NULL;
|
||||
else
|
||||
{
|
||||
dst->dacl = (struct acl *)((char *)dst + offset);
|
||||
dacl = (const ACL *)SELF_RELATIVE_FIELD( src, Dacl );
|
||||
if ((status = acl_to_samba( dacl, dst->dacl ))) return status;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!src->Owner) dst->owner_sid = NULL;
|
||||
else
|
||||
{
|
||||
dst->owner_sid = (struct sid *)((char *)dst + offset);
|
||||
if ((status = sid_to_samba( src->Owner, dst->owner_sid ))) return status;
|
||||
offset += sizeof(struct sid);
|
||||
}
|
||||
if (!src->Group) dst->group_sid = NULL;
|
||||
else
|
||||
{
|
||||
dst->group_sid = (struct sid *)((char *)dst + offset);
|
||||
if ((status = sid_to_samba( src->Group, dst->group_sid ))) return status;
|
||||
offset += sizeof(struct sid);
|
||||
}
|
||||
if (!(src->Control & SE_SACL_PRESENT)) dst->sacl = NULL;
|
||||
else
|
||||
{
|
||||
dst->sacl = (struct acl *)((char *)dst + offset);
|
||||
if ((status = acl_to_samba( src->Sacl, dst->sacl ))) return status;
|
||||
offset += dst->sacl->size;
|
||||
}
|
||||
if (!(src->Control & SE_DACL_PRESENT)) dst->dacl = NULL;
|
||||
else
|
||||
{
|
||||
dst->dacl = (struct acl *)((char *)dst + offset);
|
||||
if ((status = acl_to_samba( src->Dacl, dst->dacl ))) return status;
|
||||
}
|
||||
}
|
||||
return NERR_Success;
|
||||
}
|
||||
|
||||
static unsigned int sd_to_samba_size( const SECURITY_DESCRIPTOR *sd )
|
||||
{
|
||||
unsigned int ret = sizeof(struct security_descriptor);
|
||||
|
||||
if (sd->Owner) ret += sizeof(struct sid);
|
||||
if (sd->Group) ret += sizeof(struct sid);
|
||||
if (sd->Control & SE_SACL_PRESENT)
|
||||
ret += sizeof(struct acl) + sd->Sacl->AceCount * sizeof(struct ace);
|
||||
if (sd->Control & SE_DACL_PRESENT)
|
||||
ret += sizeof(struct acl) + sd->Dacl->AceCount * sizeof(struct ace);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static NET_API_STATUS share_info_502_to_samba( const BYTE *buf, unsigned char **bufptr )
|
||||
{
|
||||
NET_API_STATUS status;
|
||||
struct share_info_502 *ret;
|
||||
SHARE_INFO_502 *info = (SHARE_INFO_502 *)buf;
|
||||
DWORD len = 0, size = 0;
|
||||
char *ptr;
|
||||
|
||||
*bufptr = NULL;
|
||||
if (info->shi502_netname)
|
||||
len += WideCharToMultiByte( CP_UNIXCP, 0, info->shi502_netname, -1, NULL, 0, NULL, NULL );
|
||||
if (info->shi502_remark)
|
||||
len += WideCharToMultiByte( CP_UNIXCP, 0, info->shi502_remark, -1, NULL, 0, NULL, NULL );
|
||||
if (info->shi502_path)
|
||||
len += WideCharToMultiByte( CP_UNIXCP, 0, info->shi502_path, -1, NULL, 0, NULL, NULL );
|
||||
if (info->shi502_passwd)
|
||||
len += WideCharToMultiByte( CP_UNIXCP, 0, info->shi502_passwd, -1, NULL, 0, NULL, NULL );
|
||||
if (info->shi502_security_descriptor)
|
||||
size = sd_to_samba_size( info->shi502_security_descriptor );
|
||||
if (!(ret = HeapAlloc( GetProcessHeap(), 0, sizeof(*ret) + (len * sizeof(WCHAR)) + size )))
|
||||
return ERROR_OUTOFMEMORY;
|
||||
|
||||
ptr = (char *)(ret + 1);
|
||||
if (!info->shi502_netname) ret->shi502_netname = NULL;
|
||||
else
|
||||
{
|
||||
ret->shi502_netname = ptr;
|
||||
ptr += WideCharToMultiByte( CP_UNIXCP, 0, info->shi502_netname, -1, ptr, len, NULL, NULL );
|
||||
}
|
||||
ret->shi502_type = info->shi502_type;
|
||||
if (!info->shi502_remark) ret->shi502_remark = NULL;
|
||||
else
|
||||
{
|
||||
ret->shi502_remark = ptr;
|
||||
ptr += WideCharToMultiByte( CP_UNIXCP, 0, info->shi502_remark, -1, ptr, len, NULL, NULL );
|
||||
}
|
||||
ret->shi502_permissions = info->shi502_permissions;
|
||||
ret->shi502_max_uses = info->shi502_max_uses;
|
||||
ret->shi502_current_uses = info->shi502_current_uses;
|
||||
if (!info->shi502_path) ret->shi502_path = NULL;
|
||||
else
|
||||
{
|
||||
ret->shi502_path = ptr;
|
||||
ptr += WideCharToMultiByte( CP_UNIXCP, 0, info->shi502_path, -1, ptr, len, NULL, NULL );
|
||||
}
|
||||
if (!info->shi502_passwd) ret->shi502_passwd = NULL;
|
||||
else
|
||||
{
|
||||
ret->shi502_passwd = ptr;
|
||||
ptr += WideCharToMultiByte( CP_UNIXCP, 0, info->shi502_passwd, -1, ptr, len, NULL, NULL );
|
||||
}
|
||||
ret->shi502_reserved = info->shi502_reserved;
|
||||
if (!info->shi502_security_descriptor) ret->shi502_security_descriptor = NULL;
|
||||
else
|
||||
{
|
||||
status = sd_to_samba( info->shi502_security_descriptor, (struct security_descriptor *)ptr );
|
||||
if (status)
|
||||
{
|
||||
HeapFree( GetProcessHeap(), 0, ret );
|
||||
return status;
|
||||
}
|
||||
ret->shi502_security_descriptor = (struct security_descriptor *)ptr;
|
||||
}
|
||||
*bufptr = (unsigned char *)ret;
|
||||
return NERR_Success;
|
||||
}
|
||||
|
||||
static NET_API_STATUS share_info_to_samba( DWORD level, const BYTE *buf, unsigned char **bufptr )
|
||||
{
|
||||
switch (level)
|
||||
{
|
||||
case 2: return share_info_2_to_samba( buf, bufptr );
|
||||
case 502: return share_info_502_to_samba( buf, bufptr );
|
||||
default:
|
||||
FIXME( "level %u not supported\n", level );
|
||||
return ERROR_NOT_SUPPORTED;
|
||||
|
|
Loading…
Reference in New Issue