[SCM] Samba Shared Repository - branch v3-2-test updated - release-3-2-0pre2-717-gcb98996

Günther Deschner gd at samba.org
Wed Apr 9 11:25:44 GMT 2008


The branch, v3-2-test has been updated
       via  cb98996ed2ac93a0e15838048405772d2043021a (commit)
       via  0d84f0d48559d8bed91bcb478d8be0bb3b96acac (commit)
       via  08afca2188d28ff9727d0ae3f051681a1e1dc5c8 (commit)
      from  e161bb64a8348ecf7929dbc04d5923d8bd3542ad (commit)

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=v3-2-test


- Log -----------------------------------------------------------------
commit cb98996ed2ac93a0e15838048405772d2043021a
Author: Günther Deschner <gd at samba.org>
Date:   Wed Apr 9 12:38:22 2008 +0200

    Add NetUserAdd to libnetapi.
    
    Guenther

commit 0d84f0d48559d8bed91bcb478d8be0bb3b96acac
Author: Günther Deschner <gd at samba.org>
Date:   Wed Apr 9 12:36:02 2008 +0200

    Re-run make idl.
    
    Guenther

commit 08afca2188d28ff9727d0ae3f051681a1e1dc5c8
Author: Günther Deschner <gd at samba.org>
Date:   Wed Apr 9 12:35:09 2008 +0200

    Add NetUserAdd to libnetapi IDL.
    
    Guenther

-----------------------------------------------------------------------

Summary of changes:
 source/Makefile.in                    |    3 +-
 source/lib/netapi/libnetapi.c         |   46 +++++
 source/lib/netapi/libnetapi.h         |    8 +
 source/lib/netapi/netapi.h            |   24 +++
 source/lib/netapi/user.c              |  358 +++++++++++++++++++++++++++++++++
 source/librpc/gen_ndr/libnetapi.h     |   30 +++
 source/librpc/gen_ndr/ndr_libnetapi.c |  117 +++++++++++
 source/librpc/gen_ndr/ndr_libnetapi.h |   13 +-
 source/librpc/idl/libnetapi.idl       |   21 ++
 9 files changed, 618 insertions(+), 2 deletions(-)
 create mode 100644 source/lib/netapi/user.c


Changeset truncated at 500 lines:

diff --git a/source/Makefile.in b/source/Makefile.in
index cc45acd..781e8de 100644
--- a/source/Makefile.in
+++ b/source/Makefile.in
@@ -818,7 +818,8 @@ LIBNETAPI_OBJ1 = lib/netapi/netapi.o \
 		 lib/netapi/libnetapi.o \
 		 lib/netapi/joindomain.o \
 		 lib/netapi/serverinfo.o \
-		 lib/netapi/getdc.o
+		 lib/netapi/getdc.o \
+		 lib/netapi/user.o
 
 LIBNETAPI_OBJ  = $(LIBNETAPI_OBJ1) $(LIBNET_OBJ) \
 		 $(LIBSMBCONF_OBJ) \
diff --git a/source/lib/netapi/libnetapi.c b/source/lib/netapi/libnetapi.c
index ed97df2..9d92dac 100644
--- a/source/lib/netapi/libnetapi.c
+++ b/source/lib/netapi/libnetapi.c
@@ -441,3 +441,49 @@ NET_API_STATUS DsGetDcName(const char * server_name /* [in] [unique] */,
 	return r.out.result;
 }
 
+/****************************************************************
+ NetUserAdd
+****************************************************************/
+
+NET_API_STATUS NetUserAdd(const char * server_name /* [in] [unique] */,
+			  uint32_t level /* [in] */,
+			  uint8_t *buffer /* [in] [ref] */,
+			  uint32_t *parm_error /* [out] [ref] */)
+{
+	struct NetUserAdd 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.buffer = buffer;
+
+	/* Out parameters */
+	r.out.parm_error = parm_error;
+
+	if (DEBUGLEVEL >= 10) {
+		NDR_PRINT_IN_DEBUG(NetUserAdd, &r);
+	}
+
+	if (LIBNETAPI_LOCAL_SERVER(server_name)) {
+		werr = NetUserAdd_l(ctx, &r);
+	} else {
+		werr = NetUserAdd_r(ctx, &r);
+	}
+
+	r.out.result = W_ERROR_V(werr);
+
+	if (DEBUGLEVEL >= 10) {
+		NDR_PRINT_OUT_DEBUG(NetUserAdd, &r);
+	}
+
+	return r.out.result;
+}
+
diff --git a/source/lib/netapi/libnetapi.h b/source/lib/netapi/libnetapi.h
index 99c5295..8e4e73b 100644
--- a/source/lib/netapi/libnetapi.h
+++ b/source/lib/netapi/libnetapi.h
@@ -74,4 +74,12 @@ WERROR DsGetDcName_r(struct libnetapi_ctx *ctx,
 		     struct DsGetDcName *r);
 WERROR DsGetDcName_l(struct libnetapi_ctx *ctx,
 		     struct DsGetDcName *r);
+NET_API_STATUS NetUserAdd(const char * server_name /* [in] [unique] */,
+			  uint32_t level /* [in] */,
+			  uint8_t *buffer /* [in] [ref] */,
+			  uint32_t *parm_error /* [out] [ref] */);
+WERROR NetUserAdd_r(struct libnetapi_ctx *ctx,
+		    struct NetUserAdd *r);
+WERROR NetUserAdd_l(struct libnetapi_ctx *ctx,
+		    struct NetUserAdd *r);
 #endif /* __LIBNETAPI_LIBNETAPI__ */
diff --git a/source/lib/netapi/netapi.h b/source/lib/netapi/netapi.h
index 68f2372..f328f57 100644
--- a/source/lib/netapi/netapi.h
+++ b/source/lib/netapi/netapi.h
@@ -57,6 +57,21 @@ struct DOMAIN_CONTROLLER_INFO {
 	const char * client_site_name;
 };
 
+struct USER_INFO_0 {
+	const char * usri0_name;
+};
+
+struct USER_INFO_1 {
+	const char * usri1_name;
+	const char * usri1_password;
+	uint32_t usri1_password_age;
+	uint32_t usri1_priv;
+	const char * usri1_home_dir;
+	const char * usri1_comment;
+	uint32_t usri1_flags;
+	const char * usri1_script_path;
+};
+
 #endif /* _HEADER_libnetapi */
 
 /****************************************************************
@@ -176,4 +191,13 @@ NET_API_STATUS DsGetDcName(const char * server_name /* [in] [unique] */,
 			   const char * site_name /* [in] [unique] */,
 			   uint32_t flags /* [in] */,
 			   struct DOMAIN_CONTROLLER_INFO **dc_info /* [out] [ref] */);
+
+/****************************************************************
+ NetUserAdd
+****************************************************************/
+
+NET_API_STATUS NetUserAdd(const char * server_name /* [in] */,
+			  uint32_t level /* [in] */,
+			  uint8_t *buffer /* [in] [ref] */,
+			  uint32_t *parm_error /* [out] [ref] */);
 #endif
diff --git a/source/lib/netapi/user.c b/source/lib/netapi/user.c
new file mode 100644
index 0000000..71f08c2
--- /dev/null
+++ b/source/lib/netapi/user.c
@@ -0,0 +1,358 @@
+/*
+ *  Unix SMB/CIFS implementation.
+ *  NetApi User Support
+ *  Copyright (C) Guenther Deschner 2008
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "includes.h"
+
+#include "librpc/gen_ndr/libnetapi.h"
+#include "lib/netapi/netapi.h"
+#include "lib/netapi/libnetapi.h"
+
+/****************************************************************
+****************************************************************/
+
+WERROR NetUserAdd_l(struct libnetapi_ctx *ctx,
+		    struct NetUserAdd *r)
+{
+	return WERR_NOT_SUPPORTED;
+}
+
+/****************************************************************
+****************************************************************/
+
+static void convert_USER_INFO_1_to_samr_user_info25(struct USER_INFO_1 *info1,
+						    DATA_BLOB *user_session_key,
+						    struct samr_UserInfo25 *info25)
+{
+	uint32_t fields_present = SAMR_FIELD_ACCT_FLAGS;
+	struct samr_LogonHours zero_logon_hours;
+	struct lsa_BinaryString zero_parameters;
+	uint32_t acct_flags = 0;
+	NTTIME password_age;
+
+	ZERO_STRUCTP(info25);
+	ZERO_STRUCT(zero_logon_hours);
+	ZERO_STRUCT(zero_parameters);
+
+	if (info1->usri1_name) {
+		fields_present |= SAMR_FIELD_FULL_NAME;
+	}
+	if (info1->usri1_password) {
+		fields_present |= SAMR_FIELD_PASSWORD;
+	}
+	if (info1->usri1_flags) {
+		fields_present |= SAMR_FIELD_ACCT_FLAGS;
+	}
+	if (info1->usri1_name) {
+		fields_present |= SAMR_FIELD_FULL_NAME;
+	}
+	if (info1->usri1_home_dir) {
+		fields_present |= SAMR_FIELD_HOME_DIRECTORY;
+	}
+	if (info1->usri1_script_path) {
+		fields_present |= SAMR_FIELD_LOGON_SCRIPT;
+	}
+	if (info1->usri1_comment) {
+		fields_present |= SAMR_FIELD_DESCRIPTION;
+	}
+	if (info1->usri1_password_age) {
+		fields_present |= SAMR_FIELD_FORCE_PWD_CHANGE;
+	}
+
+	acct_flags |= info1->usri1_flags | ACB_NORMAL;
+
+	unix_to_nt_time_abs(&password_age, info1->usri1_password_age);
+
+	/* TODO: info1->usri1_priv */
+	init_samr_user_info21(&info25->info,
+			      0,
+			      0,
+			      0,
+			      0,
+			      0,
+			      password_age,
+			      NULL,
+			      info1->usri1_name,
+			      info1->usri1_home_dir,
+			      NULL,
+			      info1->usri1_script_path,
+			      NULL,
+			      info1->usri1_comment,
+			      NULL,
+			      NULL,
+			      &zero_parameters,
+			      0,
+			      0,
+			      acct_flags,
+			      fields_present,
+			      zero_logon_hours,
+			      0,
+			      0,
+			      0,
+			      0,
+			      0,
+			      0,
+			      0);
+
+	if (info1->usri1_password) {
+		uchar pwbuf[532];
+		struct MD5Context ctx;
+		uint8_t confounder[16];
+		DATA_BLOB confounded_session_key = data_blob(NULL, 16);
+
+		encode_pw_buffer(pwbuf, info1->usri1_password, STR_UNICODE);
+
+		generate_random_buffer((uint8_t *)confounder, 16);
+
+		MD5Init(&ctx);
+		MD5Update(&ctx, confounder, 16);
+		MD5Update(&ctx, user_session_key->data,
+				user_session_key->length);
+		MD5Final(confounded_session_key.data, &ctx);
+
+		SamOEMhashBlob(pwbuf, 516, &confounded_session_key);
+		memcpy(&pwbuf[516], confounder, 16);
+
+		memcpy(info25->password.data, pwbuf, sizeof(pwbuf));
+		data_blob_free(&confounded_session_key);
+	}
+}
+
+/****************************************************************
+****************************************************************/
+
+WERROR NetUserAdd_r(struct libnetapi_ctx *ctx,
+		    struct NetUserAdd *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, domain_handle, user_handle;
+	struct samr_SamArray *sam = NULL;
+	const char *domain_name = NULL;
+	struct lsa_String lsa_domain_name, lsa_account_name;
+	struct dom_sid2 *domain_sid = NULL;
+	struct samr_UserInfo25 info25;
+	union samr_UserInfo *user_info = NULL;
+	struct samr_PwInfo pw_info;
+	uint32_t access_granted = 0;
+	uint32_t rid = 0;
+	bool domain_found = true;
+	int i;
+	struct USER_INFO_1 *info1;
+
+	ZERO_STRUCT(connect_handle);
+	ZERO_STRUCT(domain_handle);
+	ZERO_STRUCT(user_handle);
+
+	if (!r->in.buffer) {
+		return WERR_INVALID_PARAM;
+	}
+
+	switch (r->in.level) {
+		case 1:
+			info1 = (struct USER_INFO_1 *)r->in.buffer;
+			break;
+		case 2:
+		case 3:
+		case 4:
+		default:
+			werr = WERR_NOT_SUPPORTED;
+			goto done;
+	}
+
+	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_LOOKUP_INFO_1 |
+					SAMR_DOMAIN_ACCESS_CREATE_USER |
+					SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
+					domain_sid,
+					&domain_handle);
+	if (!NT_STATUS_IS_OK(status)) {
+		werr = ntstatus_to_werror(status);
+		goto done;
+	}
+
+	init_lsa_String(&lsa_account_name, info1->usri1_name);
+
+	status = rpccli_samr_CreateUser2(pipe_cli, ctx,
+					 &domain_handle,
+					 &lsa_account_name,
+					 ACB_NORMAL,
+					 SEC_STD_WRITE_DAC |
+					 SEC_STD_DELETE |
+					 SAMR_USER_ACCESS_SET_PASSWORD |
+					 SAMR_USER_ACCESS_SET_ATTRIBUTES |
+					 SAMR_USER_ACCESS_GET_ATTRIBUTES,
+					 &user_handle,
+					 &access_granted,
+					 &rid);
+	if (!NT_STATUS_IS_OK(status)) {
+		werr = ntstatus_to_werror(status);
+		goto done;
+	}
+
+	status = rpccli_samr_QueryUserInfo(pipe_cli, ctx,
+					   &user_handle,
+					   16,
+					   &user_info);
+	if (!NT_STATUS_IS_OK(status)) {
+		werr = ntstatus_to_werror(status);
+		goto done;
+	}
+
+	if (!(user_info->info16.acct_flags & ACB_NORMAL)) {
+		werr = WERR_INVALID_PARAM;
+		goto done;
+	}
+
+	status = rpccli_samr_GetUserPwInfo(pipe_cli, ctx,
+					   &user_handle,
+					   &pw_info);
+	if (!NT_STATUS_IS_OK(status)) {
+		werr = ntstatus_to_werror(status);
+		goto done;
+	}
+
+	ZERO_STRUCTP(user_info);
+
+	convert_USER_INFO_1_to_samr_user_info25(info1,
+						&cli->user_session_key,
+						&info25);
+
+	if (info1->usri1_password) {
+		user_info->info25 = info25;
+		status = rpccli_samr_SetUserInfo2(pipe_cli, ctx,
+						  &user_handle,
+						  25,
+						  user_info);
+	} else {
+		user_info->info21 = info25.info;
+		status = rpccli_samr_SetUserInfo(pipe_cli, ctx,
+						 &user_handle,
+						 21,
+						 user_info);
+
+	}
+	if (!NT_STATUS_IS_OK(status)) {
+		werr = ntstatus_to_werror(status);
+		goto failed;
+	}
+
+	werr = WERR_OK;
+	goto done;
+
+ failed:
+	status = rpccli_samr_DeleteUser(pipe_cli, ctx,
+					&user_handle);
+	if (!NT_STATUS_IS_OK(status)) {
+		werr = ntstatus_to_werror(status);
+		goto done;
+	}
+
+ 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(&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;
+}
diff --git a/source/librpc/gen_ndr/libnetapi.h b/source/librpc/gen_ndr/libnetapi.h
index 88fe43a..5170938 100644
--- a/source/librpc/gen_ndr/libnetapi.h
+++ b/source/librpc/gen_ndr/libnetapi.h
@@ -29,6 +29,21 @@ struct DOMAIN_CONTROLLER_INFO {
 	const char * client_site_name;
 };
 
+struct USER_INFO_0 {
+	const char * usri0_name;
+};


-- 
Samba Shared Repository


More information about the samba-cvs mailing list