summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/lib/util_str.c64
-rw-r--r--source3/libsmb/smbencrypt.c36
-rw-r--r--source3/rpc_server/srv_samr_nt.c58
-rw-r--r--source3/smbd/chgpasswd.c157
4 files changed, 191 insertions, 124 deletions
diff --git a/source3/lib/util_str.c b/source3/lib/util_str.c
index f1078c6383..6d429e3719 100644
--- a/source3/lib/util_str.c
+++ b/source3/lib/util_str.c
@@ -1254,22 +1254,27 @@ char *realloc_string_sub(char *string, const char *pattern,
return string;
}
-/* Same as string_sub, but returns a talloc'ed string */
+/*
+ * Internal guts of talloc_string_sub and talloc_all_string_sub.
+ * 'filter' differentiates between them.
+ */
-char *talloc_string_sub(TALLOC_CTX *mem_ctx, const char *src,
- const char *pattern, const char *insert)
+static char *talloc_string_sub_internal(TALLOC_CTX *mem_ctx, const char *src,
+ const char *pattern, const char *insert, bool filter)
{
char *p, *in;
char *s;
char *string;
ssize_t ls,lp,li,ld, i;
- if (!insert || !pattern || !*pattern || !src || !*src)
+ if (!insert || !pattern || !*pattern || !src || !*src) {
return NULL;
+ }
string = talloc_strdup(mem_ctx, src);
if (string == NULL) {
- DEBUG(0, ("talloc_strdup failed\n"));
+ DEBUG(0, ("talloc_string_sub_internal: "
+ "talloc_strdup failed\n"));
return NULL;
}
@@ -1277,27 +1282,30 @@ char *talloc_string_sub(TALLOC_CTX *mem_ctx, const char *src,
in = SMB_STRDUP(insert);
if (!in) {
- DEBUG(0, ("talloc_string_sub: out of memory!\n"));
+ DEBUG(0, ("talloc_string_sub_internal: ENOMEM\n"));
return NULL;
}
ls = (ssize_t)strlen(s);
lp = (ssize_t)strlen(pattern);
li = (ssize_t)strlen(insert);
ld = li - lp;
- for (i=0;i<li;i++) {
- switch (in[i]) {
- case '`':
- case '"':
- case '\'':
- case ';':
- case '$':
- case '%':
- case '\r':
- case '\n':
- in[i] = '_';
- default:
- /* ok */
- break;
+
+ if (filter) {
+ for (i=0;i<li;i++) {
+ switch (in[i]) {
+ case '`':
+ case '"':
+ case '\'':
+ case ';':
+ case '$':
+ case '%':
+ case '\r':
+ case '\n':
+ in[i] = '_';
+ default:
+ /* ok */
+ break;
+ }
}
}
@@ -1325,6 +1333,14 @@ char *talloc_string_sub(TALLOC_CTX *mem_ctx, const char *src,
return string;
}
+/* Same as string_sub, but returns a talloc'ed string */
+
+char *talloc_string_sub(TALLOC_CTX *mem_ctx, const char *src,
+ const char *pattern, const char *insert)
+{
+ return talloc_string_sub_internal(mem_ctx, src, pattern, insert, true);
+}
+
/**
Similar to string_sub() but allows for any character to be substituted.
Use with caution!
@@ -1367,6 +1383,14 @@ void all_string_sub(char *s,const char *pattern,const char *insert, size_t len)
}
}
+char *talloc_all_string_sub(TALLOC_CTX *ctx,
+ const char *src,
+ const char *pattern,
+ const char *insert)
+{
+ return talloc_string_sub_internal(ctx, src, pattern, insert, false);
+}
+
/**
Similar to all_string_sub but for unicode strings.
Return a new allocated unicode string.
diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c
index 20eddff722..77ff063cb9 100644
--- a/source3/libsmb/smbencrypt.c
+++ b/source3/libsmb/smbencrypt.c
@@ -522,12 +522,17 @@ bool encode_pw_buffer(uint8 buffer[516], const char *password, int string_flags)
returned password including termination.
************************************************************/
-bool decode_pw_buffer(uint8 in_buffer[516], char *new_pwrd,
- int new_pwrd_size, uint32 *new_pw_len,
- int string_flags)
+bool decode_pw_buffer(TALLOC_CTX *ctx,
+ uint8 in_buffer[516],
+ char **pp_new_pwrd,
+ uint32 *new_pw_len,
+ int string_flags)
{
int byte_len=0;
+ *pp_new_pwrd = NULL;
+ *new_pw_len = 0;
+
/* the incoming buffer can be any alignment. */
string_flags |= STR_NOALIGN;
@@ -550,22 +555,31 @@ bool decode_pw_buffer(uint8 in_buffer[516], char *new_pwrd,
if ( (byte_len < 0) || (byte_len > 512)) {
DEBUG(0, ("decode_pw_buffer: incorrect password length (%d).\n", byte_len));
DEBUG(0, ("decode_pw_buffer: check that 'encrypt passwords = yes'\n"));
- return False;
+ return false;
}
- /* decode into the return buffer. Buffer length supplied */
- *new_pw_len = pull_string(NULL, 0, new_pwrd,
- &in_buffer[512 - byte_len], new_pwrd_size,
- byte_len, string_flags);
+ /* decode into the return buffer. */
+ *new_pw_len = pull_string_talloc(ctx,
+ NULL,
+ 0,
+ pp_new_pwrd,
+ &in_buffer[512 - byte_len],
+ byte_len,
+ string_flags);
+
+ if (!*pp_new_pwrd || *new_pw_len == 0) {
+ DEBUG(0, ("decode_pw_buffer: pull_string_talloc failed\n"));
+ return false;
+ }
#ifdef DEBUG_PASSWORD
DEBUG(100,("decode_pw_buffer: new_pwrd: "));
- dump_data(100, (uint8 *)new_pwrd, *new_pw_len);
+ dump_data(100, (uint8 *)*pp_new_pwrd, *new_pw_len);
DEBUG(100,("multibyte len:%d\n", *new_pw_len));
DEBUG(100,("original char len:%d\n", byte_len/2));
#endif
-
- return True;
+
+ return true;
}
/***********************************************************
diff --git a/source3/rpc_server/srv_samr_nt.c b/source3/rpc_server/srv_samr_nt.c
index 9aabaf08ca..3cc8f01d2c 100644
--- a/source3/rpc_server/srv_samr_nt.c
+++ b/source3/rpc_server/srv_samr_nt.c
@@ -3275,33 +3275,37 @@ static NTSTATUS set_user_info_21(TALLOC_CTX *mem_ctx, SAM_USER_INFO_21 *id21,
static NTSTATUS set_user_info_23(TALLOC_CTX *mem_ctx, SAM_USER_INFO_23 *id23,
struct samu *pwd)
{
- pstring plaintext_buf;
- uint32 len;
+ char *plaintext_buf = NULL;
+ uint32 len = 0;
uint16 acct_ctrl;
NTSTATUS status;
-
+
if (id23 == NULL) {
DEBUG(5, ("set_user_info_23: NULL id23\n"));
return NT_STATUS_INVALID_PARAMETER;
}
-
+
DEBUG(5, ("Attempting administrator password change (level 23) for user %s\n",
pdb_get_username(pwd)));
acct_ctrl = pdb_get_acct_ctrl(pwd);
- if (!decode_pw_buffer(id23->pass, plaintext_buf, 256, &len, STR_UNICODE)) {
+ if (!decode_pw_buffer(mem_ctx,
+ id23->pass,
+ &plaintext_buf,
+ &len,
+ STR_UNICODE)) {
TALLOC_FREE(pwd);
return NT_STATUS_INVALID_PARAMETER;
}
-
+
if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
TALLOC_FREE(pwd);
return NT_STATUS_ACCESS_DENIED;
}
-
+
copy_id23_to_sam_passwd(pwd, id23);
-
+
/* if it's a trust account, don't update /etc/passwd */
if ( ( (acct_ctrl & ACB_DOMTRUST) == ACB_DOMTRUST ) ||
( (acct_ctrl & ACB_WSTRUST) == ACB_WSTRUST) ||
@@ -3320,16 +3324,16 @@ static NTSTATUS set_user_info_23(TALLOC_CTX *mem_ctx, SAM_USER_INFO_23 *id23,
if ((passwd = Get_Pwnam(pdb_get_username(pwd))) == NULL) {
DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n"));
}
-
+
if(!chgpasswd(pdb_get_username(pwd), passwd, "", plaintext_buf, True)) {
TALLOC_FREE(pwd);
return NT_STATUS_ACCESS_DENIED;
}
}
}
-
- ZERO_STRUCT(plaintext_buf);
-
+
+ memset(plaintext_buf, '\0', strlen(plaintext_buf));
+
if (IS_SAM_CHANGED(pwd, PDB_GROUPSID) &&
(!NT_STATUS_IS_OK(status = pdb_set_unix_primary_group(mem_ctx,
pwd)))) {
@@ -3341,7 +3345,7 @@ static NTSTATUS set_user_info_23(TALLOC_CTX *mem_ctx, SAM_USER_INFO_23 *id23,
TALLOC_FREE(pwd);
return status;
}
-
+
TALLOC_FREE(pwd);
return NT_STATUS_OK;
@@ -3353,12 +3357,12 @@ static NTSTATUS set_user_info_23(TALLOC_CTX *mem_ctx, SAM_USER_INFO_23 *id23,
static bool set_user_info_pw(uint8 *pass, struct samu *pwd)
{
- uint32 len;
- pstring plaintext_buf;
+ uint32 len = 0;
+ char *plaintext_buf = NULL;
uint32 acct_ctrl;
time_t last_set_time;
enum pdb_value_state last_set_state;
-
+
DEBUG(5, ("Attempting administrator password change for user %s\n",
pdb_get_username(pwd)));
@@ -3368,9 +3372,11 @@ static bool set_user_info_pw(uint8 *pass, struct samu *pwd)
last_set_state = pdb_get_init_flags(pwd, PDB_PASSLASTSET);
last_set_time = pdb_get_pass_last_set_time(pwd);
- ZERO_STRUCT(plaintext_buf);
-
- if (!decode_pw_buffer(pass, plaintext_buf, 256, &len, STR_UNICODE)) {
+ if (!decode_pw_buffer(talloc_tos(),
+ pass,
+ &plaintext_buf,
+ &len,
+ STR_UNICODE)) {
TALLOC_FREE(pwd);
return False;
}
@@ -3379,7 +3385,7 @@ static bool set_user_info_pw(uint8 *pass, struct samu *pwd)
TALLOC_FREE(pwd);
return False;
}
-
+
/* if it's a trust account, don't update /etc/passwd */
if ( ( (acct_ctrl & ACB_DOMTRUST) == ACB_DOMTRUST ) ||
( (acct_ctrl & ACB_WSTRUST) == ACB_WSTRUST) ||
@@ -3399,21 +3405,21 @@ static bool set_user_info_pw(uint8 *pass, struct samu *pwd)
if ((passwd = Get_Pwnam(pdb_get_username(pwd))) == NULL) {
DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n"));
}
-
+
if(!chgpasswd(pdb_get_username(pwd), passwd, "", plaintext_buf, True)) {
TALLOC_FREE(pwd);
return False;
}
}
}
-
- ZERO_STRUCT(plaintext_buf);
-
+
+ memset(plaintext_buf, '\0', strlen(plaintext_buf));
+
/* restore last set time as this is an admin change, not a user pw change */
pdb_set_pass_last_set_time (pwd, last_set_time, last_set_state);
-
+
DEBUG(5,("set_user_info_pw: pdb_update_pwd()\n"));
-
+
/* update the SAMBA password */
if(!NT_STATUS_IS_OK(pdb_update_sam_account(pwd))) {
TALLOC_FREE(pwd);
diff --git a/source3/smbd/chgpasswd.c b/source3/smbd/chgpasswd.c
index 6e7ef208c1..aef5adb72f 100644
--- a/source3/smbd/chgpasswd.c
+++ b/source3/smbd/chgpasswd.c
@@ -25,7 +25,7 @@
* user who is attempting to change the password.
*/
-/*
+/*
* This code was copied/borrowed and stolen from various sources.
* The primary source was the poppasswd.c from the authors of POPMail. This software
* was included as a client to change passwords using the 'passwd' program
@@ -50,12 +50,12 @@
extern struct passdb_ops pdb_ops;
static NTSTATUS check_oem_password(const char *user,
- uchar password_encrypted_with_lm_hash[516],
+ uchar password_encrypted_with_lm_hash[516],
const uchar old_lm_hash_encrypted[16],
- uchar password_encrypted_with_nt_hash[516],
+ uchar password_encrypted_with_nt_hash[516],
const uchar old_nt_hash_encrypted[16],
- struct samu **hnd, char *new_passwd,
- int new_passwd_size);
+ struct samu **hnd,
+ char **pp_new_passwd);
#if ALLOW_CHANGE_PASSWORD
@@ -231,7 +231,7 @@ static int dochild(int master, const char *slavedev, const struct passwd *pass,
static int expect(int master, char *issue, char *expected)
{
- pstring buffer;
+ char buffer[1024];
int attempts, timeout, nread, len;
bool match = False;
@@ -450,13 +450,14 @@ while we were waiting\n", WTERMSIG(wstat)));
return (chstat);
}
-bool chgpasswd(const char *name, const struct passwd *pass,
+bool chgpasswd(const char *name, const struct passwd *pass,
const char *oldpass, const char *newpass, bool as_root)
{
- pstring passwordprogram;
- pstring chatsequence;
+ char *passwordprogram = NULL;
+ char *chatsequence = NULL;
size_t i;
size_t len;
+ TALLOC_CTX *ctx = talloc_tos();
if (!oldpass) {
oldpass = "";
@@ -477,7 +478,7 @@ bool chgpasswd(const char *name, const struct passwd *pass,
return (False); /* inform the user */
}
- /*
+ /*
* Check the old and new passwords don't contain any control
* characters.
*/
@@ -497,7 +498,7 @@ bool chgpasswd(const char *name, const struct passwd *pass,
return False;
}
}
-
+
#ifdef WITH_PAM
if (lp_pam_password_change()) {
bool ret;
@@ -510,7 +511,7 @@ bool chgpasswd(const char *name, const struct passwd *pass,
} else {
ret = smb_pam_passchange(name, oldpass, newpass);
}
-
+
if (as_root)
unbecome_root();
@@ -522,20 +523,18 @@ bool chgpasswd(const char *name, const struct passwd *pass,
if (pass == NULL) {
DEBUG(0, ("chgpasswd: user %s doesn't exist in the UNIX password database.\n", name));
- return False;
+ return false;
}
- pstrcpy(passwordprogram, lp_passwd_program());
- pstrcpy(chatsequence, lp_passwd_chat());
-
- if (!*chatsequence) {
- DEBUG(2, ("chgpasswd: Null chat sequence - no password changing\n"));
- return (False);
- }
-
- if (!*passwordprogram) {
+ passwordprogram = talloc_strdup(ctx, lp_passwd_program());
+ if (!passwordprogram || !*passwordprogram) {
DEBUG(2, ("chgpasswd: Null password program - no password changing\n"));
- return (False);
+ return false;
+ }
+ chatsequence = talloc_strdup(ctx, lp_passwd_chat());
+ if (!chatsequence || !*chatsequence) {
+ DEBUG(2, ("chgpasswd: Null chat sequence - no password changing\n"));
+ return false;
}
if (as_root) {
@@ -543,20 +542,38 @@ bool chgpasswd(const char *name, const struct passwd *pass,
if (strstr_m(passwordprogram, "%u") == NULL) {
DEBUG(0,("chgpasswd: Running as root the 'passwd program' parameter *MUST* contain \
the string %%u, and the given string %s does not.\n", passwordprogram ));
- return False;
+ return false;
}
}
- pstring_sub(passwordprogram, "%u", name);
+ passwordprogram = talloc_string_sub(ctx, passwordprogram, "%u", name);
+ if (!passwordprogram) {
+ return false;
+ }
+
/* note that we do NOT substitute the %o and %n in the password program
as this would open up a security hole where the user could use
a new password containing shell escape characters */
- pstring_sub(chatsequence, "%u", name);
- all_string_sub(chatsequence, "%o", oldpass, sizeof(pstring));
- all_string_sub(chatsequence, "%n", newpass, sizeof(pstring));
- return (chat_with_program
- (passwordprogram, pass, chatsequence, as_root));
+ chatsequence = talloc_string_sub(ctx, chatsequence, "%u", name);
+ if (!chatsequence) {
+ return false;
+ }
+ chatsequence = talloc_all_string_sub(ctx,
+ chatsequence,
+ "%o",
+ oldpass);
+ if (!chatsequence) {
+ return false;
+ }
+ chatsequence = talloc_all_string_sub(ctx,
+ chatsequence,
+ "%n",
+ newpass);
+ return chat_with_program(passwordprogram,
+ pass,
+ chatsequence,
+ as_root);
}
#else /* ALLOW_CHANGE_PASSWORD */
@@ -695,9 +712,9 @@ bool change_lanman_password(struct samu *sampass, uchar *pass2)
if (!pdb_set_pass_last_set_time (sampass, time(NULL), PDB_CHANGED)) {
TALLOC_FREE(sampass);
/* Not quite sure what this one qualifies as, but this will do */
- return False;
+ return False;
}
-
+
/* Now flush the sam_passwd struct to persistent storage */
ret = NT_STATUS_IS_OK(pdb_update_sam_account (sampass));
@@ -709,29 +726,32 @@ bool change_lanman_password(struct samu *sampass, uchar *pass2)
************************************************************/
NTSTATUS pass_oem_change(char *user,
- uchar password_encrypted_with_lm_hash[516],
+ uchar password_encrypted_with_lm_hash[516],
const uchar old_lm_hash_encrypted[16],
- uchar password_encrypted_with_nt_hash[516],
+ uchar password_encrypted_with_nt_hash[516],
const uchar old_nt_hash_encrypted[16],
uint32 *reject_reason)
{
- pstring new_passwd;
+ char *new_passwd = NULL;
struct samu *sampass = NULL;
- NTSTATUS nt_status = check_oem_password(user, password_encrypted_with_lm_hash,
- old_lm_hash_encrypted,
- password_encrypted_with_nt_hash,
+ NTSTATUS nt_status = check_oem_password(user,
+ password_encrypted_with_lm_hash,
+ old_lm_hash_encrypted,
+ password_encrypted_with_nt_hash,
old_nt_hash_encrypted,
- &sampass, new_passwd, sizeof(new_passwd));
-
- if (!NT_STATUS_IS_OK(nt_status))
+ &sampass,
+ &new_passwd);
+
+ if (!NT_STATUS_IS_OK(nt_status)) {
return nt_status;
+ }
/* We've already checked the old password here.... */
become_root();
nt_status = change_oem_password(sampass, NULL, new_passwd, True, reject_reason);
unbecome_root();
- memset(new_passwd, 0, sizeof(new_passwd));
+ memset(new_passwd, 0, strlen(new_passwd));
TALLOC_FREE(sampass);
@@ -739,24 +759,24 @@ NTSTATUS pass_oem_change(char *user,
}
/***********************************************************
- Decrypt and verify a user password change.
+ Decrypt and verify a user password change.
- The 516 byte long buffers are encrypted with the old NT and
- old LM passwords, and if the NT passwords are present, both
+ The 516 byte long buffers are encrypted with the old NT and
+ old LM passwords, and if the NT passwords are present, both
buffers contain a unicode string.
After decrypting the buffers, check the password is correct by
matching the old hashed passwords with the passwords in the passdb.
-
+
************************************************************/
static NTSTATUS check_oem_password(const char *user,
- uchar password_encrypted_with_lm_hash[516],
+ uchar password_encrypted_with_lm_hash[516],
const uchar old_lm_hash_encrypted[16],
- uchar password_encrypted_with_nt_hash[516],
+ uchar password_encrypted_with_nt_hash[516],
const uchar old_nt_hash_encrypted[16],
- struct samu **hnd, char *new_passwd,
- int new_passwd_size)
+ struct samu **hnd,
+ char **pp_new_passwd)
{
static uchar null_pw[16];
static uchar null_ntpw[16];
@@ -788,11 +808,11 @@ static NTSTATUS check_oem_password(const char *user,
if (ret == False) {
DEBUG(0, ("check_oem_password: getsmbpwnam returned NULL\n"));
TALLOC_FREE(sampass);
- return NT_STATUS_NO_SUCH_USER;
+ return NT_STATUS_NO_SUCH_USER;
}
acct_ctrl = pdb_get_acct_ctrl(sampass);
-
+
if (acct_ctrl & ACB_DISABLED) {
DEBUG(2,("check_lanman_password: account %s disabled.\n", user));
TALLOC_FREE(sampass);
@@ -819,7 +839,7 @@ static NTSTATUS check_oem_password(const char *user,
if (nt_pw && nt_pass_set) {
/* IDEAL Case: passwords are in unicode, and we can
- * read use the password encrypted with the NT hash
+ * read use the password encrypted with the NT hash
*/
password_encrypted = password_encrypted_with_nt_hash;
encryption_key = nt_pw;
@@ -831,7 +851,7 @@ static NTSTATUS check_oem_password(const char *user,
DEBUG(1, ("NT password change supplied for user %s, but we have no NT password to check it with\n",
user));
TALLOC_FREE(sampass);
- return NT_STATUS_WRONG_PASSWORD;
+ return NT_STATUS_WRONG_PASSWORD;
} else if (lm_pass_set) {
if (lp_lanman_auth()) {
DEBUG(1, ("LM password change supplied for user %s, but we have no LanMan password to check it with\n",
@@ -849,13 +869,16 @@ static NTSTATUS check_oem_password(const char *user,
return NT_STATUS_WRONG_PASSWORD;
}
- /*
- * Decrypt the password with the key
+ /*
+ * Decrypt the password with the key
*/
SamOEMhash( password_encrypted, encryption_key, 516);
- if ( !decode_pw_buffer(password_encrypted, new_passwd, new_passwd_size, &new_pw_len,
- nt_pass_set ? STR_UNICODE : STR_ASCII)) {
+ if (!decode_pw_buffer(talloc_tos(),
+ password_encrypted,
+ pp_new_passwd,
+ &new_pw_len,
+ nt_pass_set ? STR_UNICODE : STR_ASCII)) {
TALLOC_FREE(sampass);
return NT_STATUS_WRONG_PASSWORD;
}
@@ -867,10 +890,10 @@ static NTSTATUS check_oem_password(const char *user,
if (nt_pass_set) {
/* NT passwords, verify the NT hash. */
-
+
/* Calculate the MD4 hash (NT compatible) of the password */
memset(new_nt_hash, '\0', 16);
- E_md4hash(new_passwd, new_nt_hash);
+ E_md4hash(*pp_new_passwd, new_nt_hash);
if (nt_pw) {
/*
@@ -882,7 +905,7 @@ static NTSTATUS check_oem_password(const char *user,
TALLOC_FREE(sampass);
return NT_STATUS_WRONG_PASSWORD;
}
-
+
/* We could check the LM password here, but there is
* little point, we already know the password is
* correct, and the LM password might not even be
@@ -894,12 +917,12 @@ static NTSTATUS check_oem_password(const char *user,
* change */
#ifdef DEBUG_PASSWORD
DEBUG(100,
- ("check_oem_password: password %s ok\n", new_passwd));
+ ("check_oem_password: password %s ok\n", *pp_new_passwd));
#endif
*hnd = sampass;
return NT_STATUS_OK;
}
-
+
if (lanman_pw) {
/*
* check the lm verifier
@@ -912,7 +935,7 @@ static NTSTATUS check_oem_password(const char *user,
}
#ifdef DEBUG_PASSWORD
DEBUG(100,
- ("check_oem_password: password %s ok\n", new_passwd));
+ ("check_oem_password: password %s ok\n", *pp_new_passwd));
#endif
*hnd = sampass;
return NT_STATUS_OK;
@@ -921,7 +944,7 @@ static NTSTATUS check_oem_password(const char *user,
if (lanman_pw && lm_pass_set) {
- E_deshash(new_passwd, new_lm_hash);
+ E_deshash(*pp_new_passwd, new_lm_hash);
/*
* check the lm verifier
@@ -932,10 +955,10 @@ static NTSTATUS check_oem_password(const char *user,
TALLOC_FREE(sampass);
return NT_STATUS_WRONG_PASSWORD;
}
-
+
#ifdef DEBUG_PASSWORD
DEBUG(100,
- ("check_oem_password: password %s ok\n", new_passwd));
+ ("check_oem_password: password %s ok\n", *pp_new_passwd));
#endif
*hnd = sampass;
return NT_STATUS_OK;