summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/include/proto.h16
-rw-r--r--source3/include/smb_macros.h9
-rw-r--r--source3/rpc_client/cli_connect.c31
-rw-r--r--source3/rpc_client/cli_samr.c16
-rw-r--r--source3/rpc_client/msrpc_samr.c100
-rw-r--r--source3/rpc_parse/parse_samr.c19
-rw-r--r--source3/rpcclient/cmd_samr.c5
7 files changed, 163 insertions, 33 deletions
diff --git a/source3/include/proto.h b/source3/include/proto.h
index f9250dc04e..d6a03a8d6f 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -1802,8 +1802,10 @@ BOOL cli_connection_getsrv(const char* srv_name, const char* pipe_name,
struct cli_connection **con);
BOOL cli_connection_get(const POLICY_HND *pol, struct cli_connection **con);
BOOL cli_pol_link(POLICY_HND *to, const POLICY_HND *from);
+BOOL cli_get_con_usr_sesskey(struct cli_connection *con, uchar usr_sess_key[16]);
BOOL cli_get_con_sesskey(struct cli_connection *con, uchar sess_key[16]);
BOOL cli_con_get_srvname(struct cli_connection *con, char *srv_name);
+BOOL cli_get_usr_sesskey(const POLICY_HND *pol, uchar usr_sess_key[16]);
BOOL cli_get_sesskey(const POLICY_HND *pol, uchar sess_key[16]);
BOOL cli_get_sesskey_srv(const char* srv_name, uchar sess_key[16]);
void cli_con_gen_next_creds(struct cli_connection *con,
@@ -2033,7 +2035,7 @@ BOOL samr_open_alias( const POLICY_HND *domain_pol,
BOOL samr_del_aliasmem( POLICY_HND *alias_pol, DOM_SID *sid);
BOOL samr_add_aliasmem( POLICY_HND *alias_pol, DOM_SID *sid);
BOOL samr_delete_dom_alias( POLICY_HND *alias_pol);
-BOOL samr_create_dom_user( POLICY_HND *domain_pol, const char *acct_name,
+uint32 samr_create_dom_user( POLICY_HND *domain_pol, const char *acct_name,
uint32 unk_0, uint32 unk_1,
POLICY_HND *user_pol, uint32 *rid);
BOOL samr_create_dom_alias( POLICY_HND *domain_pol, const char *acct_name,
@@ -2057,7 +2059,7 @@ BOOL samr_open_domain( const POLICY_HND *connect_pol,
BOOL samr_query_lookup_domain( POLICY_HND *pol, const char *dom_name,
DOM_SID *dom_sid);
BOOL samr_query_lookup_names( POLICY_HND *pol, uint32 flags,
- uint32 num_names, char **names,
+ uint32 num_names, const char **names,
uint32 *num_rids,
uint32 rid[MAX_LOOKUP_SIDS],
uint32 type[MAX_LOOKUP_SIDS]);
@@ -2297,8 +2299,9 @@ uint32 msrpc_sam_enum_aliases( const char* srv_name,
ALIAS_FN(als_fn),
ALIAS_INFO_FN(als_inf_fn),
ALIAS_MEM_FN(als_mem_fn));
-BOOL create_samr_domain_user( POLICY_HND *pol_open_domain,
+BOOL create_samr_domain_user( POLICY_HND *pol_dom,
const char *acct_name, uint16 acb_info,
+ const char* password,
uint32 *rid);
BOOL create_samr_domain_alias( POLICY_HND *pol_open_domain,
const char *acct_name, const char *acct_desc,
@@ -2344,7 +2347,8 @@ BOOL get_samr_query_aliasinfo(
uint32 info_level,
uint32 alias_rid, ALIAS_INFO_CTR *ctr);
BOOL msrpc_sam_create_dom_user(const char* srv_name, DOM_SID *sid1,
- char *acct_name, uint16 acb_info,
+ const char *acct_name, uint16 acb_info,
+ const char *password,
uint32 *rid);
BOOL msrpc_sam_query_dispinfo(const char* srv_name, const char* domain,
DOM_SID *sid1,
@@ -3026,7 +3030,7 @@ BOOL make_samr_r_query_aliasmem(SAMR_R_QUERY_ALIASMEM *r_u,
BOOL samr_io_r_query_aliasmem(char *desc, SAMR_R_QUERY_ALIASMEM *r_u, prs_struct *ps, int depth);
BOOL make_samr_q_lookup_names(SAMR_Q_LOOKUP_NAMES *q_u,
POLICY_HND *pol, uint32 flags,
- uint32 num_names, char **name);
+ uint32 num_names, const char **name);
BOOL samr_io_q_lookup_names(char *desc, SAMR_Q_LOOKUP_NAMES *q_u, prs_struct *ps, int depth);
BOOL make_samr_r_lookup_names(SAMR_R_LOOKUP_NAMES *r_u,
uint32 num_rids, uint32 *rid, uint8 *type, uint32 status);
@@ -3060,7 +3064,7 @@ BOOL make_sam_user_info11(SAM_USER_INFO_11 *usr,
uint16 acct_ctrl);
BOOL sam_io_user_info11(char *desc, SAM_USER_INFO_11 *usr, prs_struct *ps, int depth);
BOOL make_sam_user_info24(SAM_USER_INFO_24 *usr,
- char newpass[516]);
+ char newpass[516], uint16 passlen);
BOOL make_sam_user_info23W(SAM_USER_INFO_23 *usr,
NTTIME *logon_time, /* all zeros */
diff --git a/source3/include/smb_macros.h b/source3/include/smb_macros.h
index 6a2d18ce83..979aec1d2c 100644
--- a/source3/include/smb_macros.h
+++ b/source3/include/smb_macros.h
@@ -2,10 +2,10 @@
Unix SMB/Netbios implementation.
Version 1.9.
SMB parameters and setup
- Copyright (C) Andrew Tridgell 1992-1998
- Copyright (C) John H Terpstra 1996-1998
- Copyright (C) Luke Kenneth Casson Leighton 1996-1998
- Copyright (C) Paul Ashton 1998
+ Copyright (C) Andrew Tridgell 1992-1999
+ Copyright (C) John H Terpstra 1996-1999
+ Copyright (C) Luke Kenneth Casson Leighton 1996-1999
+ Copyright (C) Paul Ashton 1998 - 1999
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
@@ -33,6 +33,7 @@
#define IS_BITS_SET_ALL(var,bit) (((var)&(bit))==(bit))
#define IS_BITS_SET_SOME(var,bit) (((var)&(bit))!=0)
#define IS_BITS_CLR_ALL(var,bit) (((var)&(bit))==0)
+#define IS_BITS_CLR_SOME(var,bit) (((var)&(bit))!=(bit))
/* for readability... */
#define IS_DOS_READONLY(test_mode) (((test_mode) & aRONLY) != 0)
diff --git a/source3/rpc_client/cli_connect.c b/source3/rpc_client/cli_connect.c
index d2d23864c3..d9ae71e6c9 100644
--- a/source3/rpc_client/cli_connect.c
+++ b/source3/rpc_client/cli_connect.c
@@ -308,6 +308,21 @@ BOOL cli_pol_link(POLICY_HND *to, const POLICY_HND *from)
get a user session key associated with a connection associated with a
policy handle.
****************************************************************************/
+BOOL cli_get_con_usr_sesskey(struct cli_connection *con, uchar usr_sess_key[16])
+{
+ if (con == NULL)
+ {
+ return False;
+ }
+ memcpy(usr_sess_key, con->cli->usr.pwd.sess_key, 16);
+
+ return True;
+}
+
+/****************************************************************************
+get a user session key associated with a connection associated with a
+policy handle.
+****************************************************************************/
BOOL cli_get_con_sesskey(struct cli_connection *con, uchar sess_key[16])
{
if (con == NULL)
@@ -347,6 +362,22 @@ BOOL cli_con_get_srvname(struct cli_connection *con, char *srv_name)
get a user session key associated with a connection associated with a
policy handle.
****************************************************************************/
+BOOL cli_get_usr_sesskey(const POLICY_HND *pol, uchar usr_sess_key[16])
+{
+ struct cli_connection *con = NULL;
+
+ if (!cli_connection_get(pol, &con))
+ {
+ return False;
+ }
+
+ return cli_get_con_usr_sesskey(con, usr_sess_key);
+}
+
+/****************************************************************************
+get a user session key associated with a connection associated with a
+policy handle.
+****************************************************************************/
BOOL cli_get_sesskey(const POLICY_HND *pol, uchar sess_key[16])
{
struct cli_connection *con = NULL;
diff --git a/source3/rpc_client/cli_samr.c b/source3/rpc_client/cli_samr.c
index f4308c2107..0c3da6801a 100644
--- a/source3/rpc_client/cli_samr.c
+++ b/source3/rpc_client/cli_samr.c
@@ -954,15 +954,15 @@ BOOL samr_delete_dom_alias( POLICY_HND *alias_pol)
/****************************************************************************
do a SAMR Create Domain User
****************************************************************************/
-BOOL samr_create_dom_user( POLICY_HND *domain_pol, const char *acct_name,
+uint32 samr_create_dom_user( POLICY_HND *domain_pol, const char *acct_name,
uint32 unk_0, uint32 unk_1,
POLICY_HND *user_pol, uint32 *rid)
{
prs_struct data;
prs_struct rdata;
+ uint32 status = NT_STATUS_INVALID_PARAMETER | 0xC0000000;
SAMR_Q_CREATE_USER q_o;
- BOOL valid_pol = False;
if (user_pol == NULL || domain_pol == NULL || acct_name == NULL || rid == NULL) return False;
@@ -987,26 +987,30 @@ BOOL samr_create_dom_user( POLICY_HND *domain_pol, const char *acct_name,
samr_io_r_create_user("", &r_o, &rdata, 0);
p = rdata.offset != 0;
+ status = r_o.status;
if (p && r_o.status != 0)
{
/* report error code */
DEBUG(4,("SAMR_R_CREATE_USER: %s\n", get_nt_error_msg(r_o.status)));
- p = False;
+ p = r_o.status != NT_STATUS_USER_EXISTS;
}
if (p)
{
memcpy(user_pol, &r_o.user_pol, sizeof(r_o.user_pol));
*rid = r_o.user_rid;
- valid_pol = cli_pol_link(user_pol, domain_pol);
+ if (!cli_pol_link(user_pol, domain_pol))
+ {
+ status = NT_STATUS_INVALID_HANDLE | 0xC0000000;
+ }
}
}
prs_mem_free(&data );
prs_mem_free(&rdata );
- return valid_pol;
+ return status;
}
/****************************************************************************
@@ -1632,7 +1636,7 @@ BOOL samr_query_lookup_domain( POLICY_HND *pol, const char *dom_name,
do a SAMR Query Lookup Names
****************************************************************************/
BOOL samr_query_lookup_names( POLICY_HND *pol, uint32 flags,
- uint32 num_names, char **names,
+ uint32 num_names, const char **names,
uint32 *num_rids,
uint32 rid[MAX_LOOKUP_SIDS],
uint32 type[MAX_LOOKUP_SIDS])
diff --git a/source3/rpc_client/msrpc_samr.c b/source3/rpc_client/msrpc_samr.c
index a2806463b5..f6148571aa 100644
--- a/source3/rpc_client/msrpc_samr.c
+++ b/source3/rpc_client/msrpc_samr.c
@@ -995,27 +995,111 @@ uint32 msrpc_sam_enum_aliases( const char* srv_name,
/****************************************************************************
do a SAMR create domain user
****************************************************************************/
-BOOL create_samr_domain_user( POLICY_HND *pol_open_domain,
+BOOL create_samr_domain_user( POLICY_HND *pol_dom,
const char *acct_name, uint16 acb_info,
+ const char* password,
uint32 *rid)
{
POLICY_HND pol_open_user;
BOOL ret = True;
+ BOOL res1 = True;
+ char pwbuf[516];
+ char randompw[24];
+ int plen = 0;
+ SAM_USER_INFO_24 *p24;
+ SAM_USER_INFO_16 *p16;
+ SAM_USER_INFO_16 usr16;
- if (pol_open_domain == NULL || acct_name == NULL) return False;
+ if (pol_dom == NULL || acct_name == NULL) return False;
/* send create user */
- if (!samr_create_dom_user( pol_open_domain,
+ ret = samr_create_dom_user( pol_dom,
acct_name, acb_info, 0xe005000b,
- &pol_open_user, rid))
+ &pol_open_user, rid);
+
+ if (ret == 0x0)
+ {
+ samr_close(&pol_open_user);
+ }
+
+ if (ret != 0 && ret != (NT_STATUS_USER_EXISTS | 0xC0000000))
{
return False;
}
+ if (ret == (NT_STATUS_USER_EXISTS | 0xC0000000))
+ {
+ uint32 num_rids;
+ const char *names[1];
+ uint32 type[1];
+
+ names[0] = acct_name;
+ res1 = samr_query_lookup_names( pol_dom, 0x3e8,
+ 1, names,
+ &num_rids, rid, type);
+ if (res1 == False || type[0] != SID_NAME_USER)
+ {
+ return False;
+ }
+ }
+
DEBUG(5,("create_samr_domain_user: name: %s rid 0x%x\n",
acct_name, *rid));
- return samr_close(&pol_open_user) && ret;
+ if (IS_BITS_SET_SOME(acb_info, ACB_NORMAL | ACB_DOMTRUST) &&
+ password == NULL)
+ {
+ return True;
+ }
+
+ if (password == NULL)
+ {
+ generate_random_buffer(randompw, sizeof(randompw), True);
+ password = randompw;
+ plen = sizeof(randompw);
+ }
+ else
+ {
+ plen = strlen(password);
+ }
+ encode_pw_buffer(pwbuf, password, plen, False);
+
+ p24 = (SAM_USER_INFO_24*)malloc(sizeof(SAM_USER_INFO_24));
+ if (p24 == NULL)
+ {
+ return False;
+ }
+
+ make_sam_user_info24(p24, pwbuf, plen);
+
+ res1 = set_samr_set_userinfo( pol_dom, 0x18, *rid, (void*)p24);
+
+ if (res1 == False)
+ {
+ return False;
+ }
+
+ /* send set user info */
+ res1 = get_samr_query_userinfo( pol_dom, 0x10, *rid, (void*)&usr16);
+
+ if (res1 == False)
+ {
+ return False;
+ }
+
+ if (usr16.acb_info != acb_info)
+ {
+ p16 = (SAM_USER_INFO_16 *) malloc(sizeof(SAM_USER_INFO_16));
+ if (p16 == NULL)
+ {
+ return False;
+ }
+ p16->acb_info = usr16.acb_info;
+
+ res1 = set_samr_set_userinfo2( pol_dom, 0x10, *rid, (void*)p16);
+ }
+
+ return res1;
}
/****************************************************************************
@@ -1440,7 +1524,8 @@ BOOL get_samr_query_aliasinfo(
SAM create domain user.
****************************************************************************/
BOOL msrpc_sam_create_dom_user(const char* srv_name, DOM_SID *sid1,
- char *acct_name, uint16 acb_info,
+ const char *acct_name, uint16 acb_info,
+ const char *password,
uint32 *rid)
{
BOOL res = True;
@@ -1464,7 +1549,8 @@ BOOL msrpc_sam_create_dom_user(const char* srv_name, DOM_SID *sid1,
/* create a domain user */
res2 = res1 ? create_samr_domain_user(
&pol_dom,
- acct_name, acb_info, &user_rid) : False;
+ acct_name,
+ acb_info, password, &user_rid) : False;
res1 = res1 ? samr_close( &pol_dom) : False;
res = res ? samr_close( &sam_pol) : False;
diff --git a/source3/rpc_parse/parse_samr.c b/source3/rpc_parse/parse_samr.c
index e9d425d869..45dc5b57c8 100644
--- a/source3/rpc_parse/parse_samr.c
+++ b/source3/rpc_parse/parse_samr.c
@@ -4399,7 +4399,7 @@ makes a SAMR_Q_LOOKUP_NAMES structure.
********************************************************************/
BOOL make_samr_q_lookup_names(SAMR_Q_LOOKUP_NAMES *q_u,
POLICY_HND *pol, uint32 flags,
- uint32 num_names, char **name)
+ uint32 num_names, const char **name)
{
uint32 i;
if (q_u == NULL) return False;
@@ -4937,10 +4937,10 @@ BOOL sam_io_user_info11(char *desc, SAM_USER_INFO_11 *usr, prs_struct *ps, int
*************************************************************************/
BOOL make_sam_user_info24(SAM_USER_INFO_24 *usr,
- char newpass[516])
+ char newpass[516], uint16 passlen)
{
memcpy(usr->pass, newpass, sizeof(usr->pass));
- usr->unk_0 = 0x44;
+ usr->unk_0 = passlen;
return True;
}
@@ -4948,7 +4948,7 @@ BOOL make_sam_user_info24(SAM_USER_INFO_24 *usr,
/*******************************************************************
reads or writes a structure.
********************************************************************/
-static BOOL sam_io_user_info24(char *desc, SAM_USER_INFO_24 *usr, prs_struct *ps, int depth)
+static BOOL sam_io_user_info24(char *desc, SAM_USER_INFO_24 *usr, prs_struct *ps, int depth)
{
if (usr == NULL) return False;
@@ -5673,26 +5673,29 @@ BOOL make_samr_q_set_userinfo(SAMR_Q_SET_USERINFO *q_u,
case 0x18:
{
uchar sess_key[16];
- if (!cli_get_sesskey(hnd, sess_key))
+ if (!cli_get_usr_sesskey(hnd, sess_key))
{
return False;
}
+ SamOEMhash(q_u->info.id24->pass, sess_key, 1);
#ifdef DEBUG_PASSWORD
dump_data(100, sess_key, 16);
+ dump_data(100, q_u->info.id24->pass, 516);
#endif
- SamOEMhash(q_u->info.id24->pass, sess_key, 1);
+ break;
}
case 0x17:
{
uchar sess_key[16];
- if (!cli_get_sesskey(hnd, sess_key))
+ if (!cli_get_usr_sesskey(hnd, sess_key))
{
return False;
}
+ SamOEMhash(q_u->info.id23->pass, sess_key, 1);
#ifdef DEBUG_PASSWORD
dump_data(100, sess_key, 16);
+ dump_data(100, q_u->info.id23->pass, 516);
#endif
- SamOEMhash(q_u->info.id23->pass, sess_key, 1);
break;
}
default:
diff --git a/source3/rpcclient/cmd_samr.c b/source3/rpcclient/cmd_samr.c
index f38587ceb6..a8ab18f6b8 100644
--- a/source3/rpcclient/cmd_samr.c
+++ b/source3/rpcclient/cmd_samr.c
@@ -749,7 +749,8 @@ void cmd_sam_create_dom_user(struct client_info *info, int argc, char *argv[])
pwdb_encode_acct_ctrl(acb_info, NEW_PW_FORMAT_SPACE_PADDED_LEN));
if (msrpc_sam_create_dom_user(srv_name, &sid1,
- acct_name, acb_info, &user_rid))
+ acct_name, acb_info, NULL,
+ &user_rid))
{
report(out_hnd, "Create Domain User: OK\n");
}
@@ -1863,7 +1864,7 @@ void cmd_sam_set_userinfo(struct client_info *info, int argc, char *argv[])
if (True)
{
SAM_USER_INFO_24 *p = (SAM_USER_INFO_24*)malloc(sizeof(SAM_USER_INFO_24));
- make_sam_user_info24(p, pwbuf);
+ make_sam_user_info24(p, pwbuf, strlen(password));
usr = p;
switch_value = 24;