summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/lib/netapi/libnetapi.c42
-rw-r--r--source3/lib/netapi/libnetapi.h6
-rw-r--r--source3/lib/netapi/netapi.h8
-rw-r--r--source3/lib/netapi/user.c190
4 files changed, 246 insertions, 0 deletions
diff --git a/source3/lib/netapi/libnetapi.c b/source3/lib/netapi/libnetapi.c
index 9d92dac39f..7fd1e76ebd 100644
--- a/source3/lib/netapi/libnetapi.c
+++ b/source3/lib/netapi/libnetapi.c
@@ -487,3 +487,45 @@ NET_API_STATUS NetUserAdd(const char * server_name /* [in] [unique] */,
return r.out.result;
}
+/****************************************************************
+ NetUserDel
+****************************************************************/
+
+NET_API_STATUS NetUserDel(const char * server_name /* [in] [unique] */,
+ const char * user_name /* [in] [ref] */)
+{
+ struct NetUserDel 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.user_name = user_name;
+
+ /* Out parameters */
+
+ if (DEBUGLEVEL >= 10) {
+ NDR_PRINT_IN_DEBUG(NetUserDel, &r);
+ }
+
+ if (LIBNETAPI_LOCAL_SERVER(server_name)) {
+ werr = NetUserDel_l(ctx, &r);
+ } else {
+ werr = NetUserDel_r(ctx, &r);
+ }
+
+ r.out.result = W_ERROR_V(werr);
+
+ if (DEBUGLEVEL >= 10) {
+ NDR_PRINT_OUT_DEBUG(NetUserDel, &r);
+ }
+
+ return r.out.result;
+}
+
diff --git a/source3/lib/netapi/libnetapi.h b/source3/lib/netapi/libnetapi.h
index 8e4e73bcd8..9ab5481164 100644
--- a/source3/lib/netapi/libnetapi.h
+++ b/source3/lib/netapi/libnetapi.h
@@ -82,4 +82,10 @@ WERROR NetUserAdd_r(struct libnetapi_ctx *ctx,
struct NetUserAdd *r);
WERROR NetUserAdd_l(struct libnetapi_ctx *ctx,
struct NetUserAdd *r);
+NET_API_STATUS NetUserDel(const char * server_name /* [in] [unique] */,
+ const char * user_name /* [in] [ref] */);
+WERROR NetUserDel_r(struct libnetapi_ctx *ctx,
+ struct NetUserDel *r);
+WERROR NetUserDel_l(struct libnetapi_ctx *ctx,
+ struct NetUserDel *r);
#endif /* __LIBNETAPI_LIBNETAPI__ */
diff --git a/source3/lib/netapi/netapi.h b/source3/lib/netapi/netapi.h
index f328f57946..67919eeb01 100644
--- a/source3/lib/netapi/netapi.h
+++ b/source3/lib/netapi/netapi.h
@@ -200,4 +200,12 @@ NET_API_STATUS NetUserAdd(const char * server_name /* [in] */,
uint32_t level /* [in] */,
uint8_t *buffer /* [in] [ref] */,
uint32_t *parm_error /* [out] [ref] */);
+
+/****************************************************************
+ NetUserDel
+****************************************************************/
+
+NET_API_STATUS NetUserDel(const char * server_name /* [in] */,
+ const char * user_name /* [in] */);
+
#endif
diff --git a/source3/lib/netapi/user.c b/source3/lib/netapi/user.c
index 71f08c2b21..f5bdc27fd8 100644
--- a/source3/lib/netapi/user.c
+++ b/source3/lib/netapi/user.c
@@ -356,3 +356,193 @@ WERROR NetUserAdd_r(struct libnetapi_ctx *ctx,
return werr;
}
+
+/****************************************************************
+****************************************************************/
+
+WERROR NetUserDel_r(struct libnetapi_ctx *ctx,
+ struct NetUserDel *r)
+{
+ struct cli_state *cli = NULL;
+ struct rpc_pipe_client *pipe_cli = NULL;
+ NTSTATUS status;
+ WERROR werr;
+ uint32_t resume_handle = 0;
+ uint32_t num_entries = 0;
+ POLICY_HND connect_handle, builtin_handle, domain_handle, user_handle;
+ struct samr_SamArray *sam = NULL;
+ const char *domain_name = NULL;
+ struct lsa_String lsa_domain_name, lsa_account_name;
+ struct samr_Ids user_rids, name_types;
+ struct dom_sid2 *domain_sid = NULL;
+ struct dom_sid2 user_sid;
+ bool domain_found = true;
+ int i;
+
+ ZERO_STRUCT(connect_handle);
+ ZERO_STRUCT(builtin_handle);
+ ZERO_STRUCT(domain_handle);
+ ZERO_STRUCT(user_handle);
+
+ 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_ENUM_DOMAINS |
+ SAMR_ACCESS_OPEN_DOMAIN,
+ &connect_handle);
+ if (!NT_STATUS_IS_OK(status)) {
+ werr = ntstatus_to_werror(status);
+ goto done;
+ }
+
+ status = rpccli_samr_EnumDomains(pipe_cli, ctx,
+ &connect_handle,
+ &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_OPEN_ACCOUNT,
+ domain_sid,
+ &domain_handle);
+ 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_OPEN_ACCOUNT,
+ CONST_DISCARD(DOM_SID *, &global_sid_Builtin),
+ &builtin_handle);
+ if (!NT_STATUS_IS_OK(status)) {
+ werr = ntstatus_to_werror(status);
+ goto done;
+ }
+
+ init_lsa_String(&lsa_account_name, r->in.user_name);
+
+ status = rpccli_samr_LookupNames(pipe_cli, ctx,
+ &domain_handle,
+ 1,
+ &lsa_account_name,
+ &user_rids,
+ &name_types);
+ if (!NT_STATUS_IS_OK(status)) {
+ werr = ntstatus_to_werror(status);
+ goto done;
+ }
+
+ status = rpccli_samr_OpenUser(pipe_cli, ctx,
+ &domain_handle,
+ STD_RIGHT_DELETE_ACCESS,
+ user_rids.ids[0],
+ &user_handle);
+ if (!NT_STATUS_IS_OK(status)) {
+ werr = ntstatus_to_werror(status);
+ goto done;
+ }
+
+ sid_compose(&user_sid, domain_sid, user_rids.ids[0]);
+
+ status = rpccli_samr_RemoveMemberFromForeignDomain(pipe_cli, ctx,
+ &builtin_handle,
+ &user_sid);
+ if (!NT_STATUS_IS_OK(status)) {
+ werr = ntstatus_to_werror(status);
+ goto done;
+ }
+
+ status = rpccli_samr_DeleteUser(pipe_cli, ctx,
+ &user_handle);
+ if (!NT_STATUS_IS_OK(status)) {
+ werr = ntstatus_to_werror(status);
+ goto done;
+ }
+
+ werr = WERR_OK;
+
+ done:
+ if (!cli) {
+ return werr;
+ }
+
+ if (is_valid_policy_hnd(&user_handle)) {
+ rpccli_samr_Close(pipe_cli, ctx, &user_handle);
+ }
+ if (is_valid_policy_hnd(&builtin_handle)) {
+ rpccli_samr_Close(pipe_cli, ctx, &builtin_handle);
+ }
+ 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);
+ }
+
+ cli_shutdown(cli);
+
+ return werr;
+}
+
+/****************************************************************
+****************************************************************/
+
+WERROR NetUserDel_l(struct libnetapi_ctx *ctx,
+ struct NetUserDel *r)
+{
+ return WERR_NOT_SUPPORTED;
+}