mirror of
https://github.com/samba-team/samba.git
synced 2025-01-13 13:18:06 +03:00
Add NetUserEnum to libnetapi.
Guenther
This commit is contained in:
parent
285072479b
commit
6c933d0b38
@ -529,3 +529,58 @@ NET_API_STATUS NetUserDel(const char * server_name /* [in] [unique] */,
|
||||
return r.out.result;
|
||||
}
|
||||
|
||||
/****************************************************************
|
||||
NetUserEnum
|
||||
****************************************************************/
|
||||
|
||||
NET_API_STATUS NetUserEnum(const char * server_name /* [in] [unique] */,
|
||||
uint32_t level /* [in] */,
|
||||
uint32_t filter /* [in] */,
|
||||
uint8_t **buffer /* [out] [ref] */,
|
||||
uint32_t prefmaxlen /* [in] */,
|
||||
uint32_t *entries_read /* [out] [ref] */,
|
||||
uint32_t *total_entries /* [out] [ref] */,
|
||||
uint32_t *resume_handle /* [in,out] [ref] */)
|
||||
{
|
||||
struct NetUserEnum r;
|
||||
struct libnetapi_ctx *ctx = NULL;
|
||||
NET_API_STATUS status;
|
||||
WERROR werr;
|
||||
|
||||
status = libnetapi_getctx(&ctx);
|
||||
if (status != 0) {
|
||||
return status;
|
||||
}
|
||||
|
||||
/* In parameters */
|
||||
r.in.server_name = server_name;
|
||||
r.in.level = level;
|
||||
r.in.filter = filter;
|
||||
r.in.prefmaxlen = prefmaxlen;
|
||||
r.in.resume_handle = resume_handle;
|
||||
|
||||
/* Out parameters */
|
||||
r.out.buffer = buffer;
|
||||
r.out.entries_read = entries_read;
|
||||
r.out.total_entries = total_entries;
|
||||
r.out.resume_handle = resume_handle;
|
||||
|
||||
if (DEBUGLEVEL >= 10) {
|
||||
NDR_PRINT_IN_DEBUG(NetUserEnum, &r);
|
||||
}
|
||||
|
||||
if (LIBNETAPI_LOCAL_SERVER(server_name)) {
|
||||
werr = NetUserEnum_l(ctx, &r);
|
||||
} else {
|
||||
werr = NetUserEnum_r(ctx, &r);
|
||||
}
|
||||
|
||||
r.out.result = W_ERROR_V(werr);
|
||||
|
||||
if (DEBUGLEVEL >= 10) {
|
||||
NDR_PRINT_OUT_DEBUG(NetUserEnum, &r);
|
||||
}
|
||||
|
||||
return r.out.result;
|
||||
}
|
||||
|
||||
|
@ -88,4 +88,16 @@ WERROR NetUserDel_r(struct libnetapi_ctx *ctx,
|
||||
struct NetUserDel *r);
|
||||
WERROR NetUserDel_l(struct libnetapi_ctx *ctx,
|
||||
struct NetUserDel *r);
|
||||
NET_API_STATUS NetUserEnum(const char * server_name /* [in] [unique] */,
|
||||
uint32_t level /* [in] */,
|
||||
uint32_t filter /* [in] */,
|
||||
uint8_t **buffer /* [out] [ref] */,
|
||||
uint32_t prefmaxlen /* [in] */,
|
||||
uint32_t *entries_read /* [out] [ref] */,
|
||||
uint32_t *total_entries /* [out] [ref] */,
|
||||
uint32_t *resume_handle /* [in,out] [ref] */);
|
||||
WERROR NetUserEnum_r(struct libnetapi_ctx *ctx,
|
||||
struct NetUserEnum *r);
|
||||
WERROR NetUserEnum_l(struct libnetapi_ctx *ctx,
|
||||
struct NetUserEnum *r);
|
||||
#endif /* __LIBNETAPI_LIBNETAPI__ */
|
||||
|
@ -23,11 +23,12 @@
|
||||
/****************************************************************
|
||||
NET_API_STATUS
|
||||
****************************************************************/
|
||||
|
||||
typedef enum {
|
||||
NET_API_STATUS_SUCCESS = 0
|
||||
} NET_API_STATUS;
|
||||
|
||||
#define ERROR_MORE_DATA ( 234L )
|
||||
|
||||
/****************************************************************
|
||||
****************************************************************/
|
||||
|
||||
@ -208,4 +209,17 @@ NET_API_STATUS NetUserAdd(const char * server_name /* [in] */,
|
||||
NET_API_STATUS NetUserDel(const char * server_name /* [in] */,
|
||||
const char * user_name /* [in] */);
|
||||
|
||||
/****************************************************************
|
||||
NetUserEnum
|
||||
****************************************************************/
|
||||
|
||||
NET_API_STATUS NetUserEnum(const char * server_name /* [in] */,
|
||||
uint32_t level /* [in] */,
|
||||
uint32_t filter /* [in] */,
|
||||
uint8_t **buffer /* [out] [ref] */,
|
||||
uint32_t prefmaxlen /* [in] */,
|
||||
uint32_t *entries_read /* [out] [ref] */,
|
||||
uint32_t *total_entries /* [out] [ref] */,
|
||||
uint32_t *resume_handle /* [in,out] [ref] */);
|
||||
|
||||
#endif
|
||||
|
@ -546,3 +546,200 @@ WERROR NetUserDel_l(struct libnetapi_ctx *ctx,
|
||||
{
|
||||
return WERR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
/****************************************************************
|
||||
****************************************************************/
|
||||
|
||||
static WERROR convert_samr_samarray_to_USER_INFO_buffer(TALLOC_CTX *mem_ctx,
|
||||
struct samr_SamArray *sam_array,
|
||||
uint32_t level,
|
||||
uint8_t **buffer)
|
||||
{
|
||||
struct USER_INFO_0 *info0 = NULL;
|
||||
int i;
|
||||
|
||||
switch (level) {
|
||||
case 0:
|
||||
info0 = TALLOC_ZERO_ARRAY(mem_ctx, struct USER_INFO_0,
|
||||
sam_array->count);
|
||||
W_ERROR_HAVE_NO_MEMORY(info0);
|
||||
|
||||
for (i=0; i<sam_array->count; i++) {
|
||||
info0[i].usri0_name = talloc_strdup(mem_ctx,
|
||||
sam_array->entries[i].name.string);
|
||||
W_ERROR_HAVE_NO_MEMORY(info0[i].usri0_name);
|
||||
}
|
||||
|
||||
*buffer = (uint8_t *)talloc_memdup(mem_ctx, info0,
|
||||
sizeof(struct USER_INFO_0) * sam_array->count);
|
||||
W_ERROR_HAVE_NO_MEMORY(*buffer);
|
||||
break;
|
||||
default:
|
||||
return WERR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
return WERR_OK;
|
||||
}
|
||||
|
||||
/****************************************************************
|
||||
****************************************************************/
|
||||
|
||||
WERROR NetUserEnum_r(struct libnetapi_ctx *ctx,
|
||||
struct NetUserEnum *r)
|
||||
{
|
||||
struct cli_state *cli = NULL;
|
||||
struct rpc_pipe_client *pipe_cli = NULL;
|
||||
struct policy_handle connect_handle;
|
||||
struct dom_sid2 *domain_sid = NULL;
|
||||
struct policy_handle domain_handle;
|
||||
struct samr_SamArray *sam = NULL;
|
||||
uint32_t num_entries = 0;
|
||||
int i;
|
||||
const char *domain_name = NULL;
|
||||
bool domain_found = true;
|
||||
uint32_t dom_resume_handle = 0;
|
||||
struct lsa_String lsa_domain_name;
|
||||
|
||||
NTSTATUS status;
|
||||
WERROR werr;
|
||||
|
||||
ZERO_STRUCT(connect_handle);
|
||||
ZERO_STRUCT(domain_handle);
|
||||
|
||||
switch (r->in.level) {
|
||||
case 0:
|
||||
break;
|
||||
case 1:
|
||||
case 2:
|
||||
case 3:
|
||||
case 10:
|
||||
case 11:
|
||||
case 20:
|
||||
case 23:
|
||||
default:
|
||||
return WERR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
status = cli_full_connection(&cli, NULL, r->in.server_name,
|
||||
NULL, 0,
|
||||
"IPC$", "IPC",
|
||||
ctx->username,
|
||||
ctx->workgroup,
|
||||
ctx->password,
|
||||
CLI_FULL_CONNECTION_USE_KERBEROS |
|
||||
CLI_FULL_CONNECTION_FALLBACK_AFTER_KERBEROS,
|
||||
Undefined, NULL);
|
||||
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
werr = ntstatus_to_werror(status);
|
||||
goto done;
|
||||
}
|
||||
|
||||
pipe_cli = cli_rpc_pipe_open_noauth(cli, PI_SAMR, &status);
|
||||
if (!pipe_cli) {
|
||||
werr = ntstatus_to_werror(status);
|
||||
goto done;
|
||||
}
|
||||
|
||||
status = rpccli_try_samr_connects(pipe_cli, ctx,
|
||||
SAMR_ACCESS_OPEN_DOMAIN |
|
||||
SAMR_ACCESS_ENUM_DOMAINS,
|
||||
&connect_handle);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
werr = ntstatus_to_werror(status);
|
||||
goto done;
|
||||
}
|
||||
|
||||
status = rpccli_samr_EnumDomains(pipe_cli, ctx,
|
||||
&connect_handle,
|
||||
&dom_resume_handle,
|
||||
&sam,
|
||||
0xffffffff,
|
||||
&num_entries);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
werr = ntstatus_to_werror(status);
|
||||
goto done;
|
||||
}
|
||||
|
||||
for (i=0; i<num_entries; i++) {
|
||||
|
||||
domain_name = sam->entries[i].name.string;
|
||||
|
||||
if (strequal(domain_name, builtin_domain_name())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
domain_found = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!domain_found) {
|
||||
werr = WERR_NO_SUCH_DOMAIN;
|
||||
goto done;
|
||||
}
|
||||
|
||||
init_lsa_String(&lsa_domain_name, domain_name);
|
||||
|
||||
status = rpccli_samr_LookupDomain(pipe_cli, ctx,
|
||||
&connect_handle,
|
||||
&lsa_domain_name,
|
||||
&domain_sid);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
werr = ntstatus_to_werror(status);
|
||||
goto done;
|
||||
}
|
||||
|
||||
status = rpccli_samr_OpenDomain(pipe_cli,
|
||||
ctx,
|
||||
&connect_handle,
|
||||
SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2 |
|
||||
SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS |
|
||||
SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
|
||||
domain_sid,
|
||||
&domain_handle);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
werr = ntstatus_to_werror(status);
|
||||
goto done;
|
||||
}
|
||||
|
||||
status = rpccli_samr_EnumDomainUsers(pipe_cli,
|
||||
ctx,
|
||||
&domain_handle,
|
||||
r->in.resume_handle,
|
||||
r->in.filter,
|
||||
&sam,
|
||||
r->in.prefmaxlen,
|
||||
r->out.entries_read);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
werr = ntstatus_to_werror(status);
|
||||
goto done;
|
||||
}
|
||||
|
||||
werr = convert_samr_samarray_to_USER_INFO_buffer(ctx, sam,
|
||||
r->in.level,
|
||||
r->out.buffer);
|
||||
|
||||
done:
|
||||
if (is_valid_policy_hnd(&domain_handle)) {
|
||||
rpccli_samr_Close(pipe_cli, ctx, &domain_handle);
|
||||
}
|
||||
if (is_valid_policy_hnd(&connect_handle)) {
|
||||
rpccli_samr_Close(pipe_cli, ctx, &connect_handle);
|
||||
}
|
||||
|
||||
if (cli) {
|
||||
cli_shutdown(cli);
|
||||
}
|
||||
|
||||
return werr;
|
||||
}
|
||||
|
||||
/****************************************************************
|
||||
****************************************************************/
|
||||
|
||||
WERROR NetUserEnum_l(struct libnetapi_ctx *ctx,
|
||||
struct NetUserEnum *r)
|
||||
{
|
||||
return WERR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user