summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuke Leighton <lkcl@samba.org>1999-11-18 19:29:08 +0000
committerLuke Leighton <lkcl@samba.org>1999-11-18 19:29:08 +0000
commite3b2f276e04bce6365dfb1a7e0b904b7c788c364 (patch)
treecde4610ae1e2d3ac6c635fd9a2f8cc4599c17ad1
parenta394a4a8fa2c4c0ff03fbc5bc4ea925245ec1fed (diff)
downloadsamba-e3b2f276e04bce6365dfb1a7e0b904b7c788c364.tar.gz
samba-e3b2f276e04bce6365dfb1a7e0b904b7c788c364.tar.bz2
samba-e3b2f276e04bce6365dfb1a7e0b904b7c788c364.zip
added samuserset2 rpcclient command to test ACB_XXX bit-setting on
samr opcode 0x25. _yet_ another failed attempt to get nt5rc2 to join a samba domain. what _is_ it with this stuff, dammit? (This used to be commit c3913f8ae272c496fc4519141accf01ee9f1e49e)
-rw-r--r--source3/include/proto.h20
-rw-r--r--source3/include/rpc_samr.h35
-rw-r--r--source3/rpc_client/cli_samr.c97
-rw-r--r--source3/rpc_parse/parse_samr.c161
-rw-r--r--source3/rpc_server/srv_samr.c107
-rw-r--r--source3/rpcclient/cmd_samr.c156
-rw-r--r--source3/rpcclient/rpcclient.c6
7 files changed, 571 insertions, 11 deletions
diff --git a/source3/include/proto.h b/source3/include/proto.h
index 5183f5dfb0..43780df9f8 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -1874,7 +1874,7 @@ BOOL do_reg_query_key(struct cli_state *cli, uint16 fnum, POLICY_HND *hnd,
BOOL do_reg_unknown_1a(struct cli_state *cli, uint16 fnum, POLICY_HND *hnd, uint32 *unk);
BOOL do_reg_query_info(struct cli_state *cli, uint16 fnum, POLICY_HND *hnd,
const char* val_name,
- uint32 *type, BUFFER2 *buf);
+ uint32 *type, BUFFER2 *buffer);
BOOL do_reg_set_key_sec(struct cli_state *cli, uint16 fnum, POLICY_HND *hnd,
uint32 sec_buf_size, SEC_DESC *sec_buf);
BOOL do_reg_get_key_sec(struct cli_state *cli, uint16 fnum, POLICY_HND *hnd,
@@ -1933,6 +1933,10 @@ BOOL delete_samr_dom_alias(struct cli_state *cli, uint16 fnum,
BOOL get_samr_query_aliasmem(struct cli_state *cli, uint16 fnum,
const POLICY_HND *pol_open_domain,
uint32 alias_rid, uint32 *num_mem, DOM_SID2 *sid);
+BOOL set_samr_set_userinfo2(struct cli_state *cli, uint16 fnum,
+ POLICY_HND *pol_open_domain,
+ uint32 info_level,
+ uint32 user_rid, void *usr);
BOOL set_samr_set_userinfo(struct cli_state *cli, uint16 fnum,
POLICY_HND *pol_open_domain,
uint32 info_level,
@@ -1940,7 +1944,7 @@ BOOL set_samr_set_userinfo(struct cli_state *cli, uint16 fnum,
BOOL get_samr_query_userinfo(struct cli_state *cli, uint16 fnum,
POLICY_HND *pol_open_domain,
uint32 info_level,
- uint32 user_rid, SAM_USER_INFO_21 *usr);
+ uint32 user_rid, void *usr);
BOOL get_samr_query_groupinfo(struct cli_state *cli, uint16 fnum,
const POLICY_HND *pol_open_domain,
uint32 info_level,
@@ -2056,6 +2060,9 @@ BOOL samr_query_usergroups(struct cli_state *cli, uint16 fnum,
BOOL samr_query_groupinfo(struct cli_state *cli, uint16 fnum,
POLICY_HND *pol,
uint16 switch_value, GROUP_INFO_CTR* ctr);
+BOOL samr_set_userinfo2(struct cli_state *cli, uint16 fnum,
+ POLICY_HND *pol, uint16 switch_value,
+ void* usr);
BOOL samr_set_userinfo(struct cli_state *cli, uint16 fnum,
POLICY_HND *pol, uint16 switch_value, void* usr);
BOOL samr_query_userinfo(struct cli_state *cli, uint16 fnum,
@@ -2942,6 +2949,14 @@ BOOL samr_io_q_set_userinfo(char *desc, SAMR_Q_SET_USERINFO *q_u, prs_struct *ps
void free_samr_q_set_userinfo(SAMR_Q_SET_USERINFO *q_u);
BOOL make_samr_r_set_userinfo(SAMR_R_SET_USERINFO *r_u, uint32 status);
BOOL samr_io_r_set_userinfo(char *desc, SAMR_R_SET_USERINFO *r_u, prs_struct *ps, int depth);
+BOOL make_samr_q_set_userinfo2(SAMR_Q_SET_USERINFO2 *q_u,
+ POLICY_HND *hnd,
+ uint16 switch_value, void *info);
+BOOL samr_io_q_set_userinfo2(char *desc, SAMR_Q_SET_USERINFO2 *q_u, prs_struct *ps, int depth);
+void free_samr_q_set_userinfo2(SAMR_Q_SET_USERINFO2 *q_u);
+BOOL make_samr_r_set_userinfo2(SAMR_R_SET_USERINFO2 *r_u,
+ uint32 status);
+BOOL samr_io_r_set_userinfo2(char *desc, SAMR_R_SET_USERINFO2 *r_u, prs_struct *ps, int depth);
BOOL make_samr_q_connect(SAMR_Q_CONNECT *q_u,
const char *srv_name, uint32 unknown_0);
BOOL samr_io_q_connect(char *desc, SAMR_Q_CONNECT *q_u, prs_struct *ps, int depth);
@@ -3492,6 +3507,7 @@ void cmd_sam_enum_users(struct client_info *info);
void cmd_sam_query_groupmem(struct client_info *info);
void cmd_sam_query_group(struct client_info *info);
void cmd_sam_query_user(struct client_info *info);
+void cmd_sam_set_userinfo2(struct client_info *info);
void cmd_sam_set_userinfo(struct client_info *info);
void cmd_sam_query_dispinfo(struct client_info *info);
void cmd_sam_query_dominfo(struct client_info *info);
diff --git a/source3/include/rpc_samr.h b/source3/include/rpc_samr.h
index 850e3a8b94..2c9a719ff5 100644
--- a/source3/include/rpc_samr.h
+++ b/source3/include/rpc_samr.h
@@ -114,11 +114,12 @@ SamrTestPrivateFunctionsUser
#define SAMR_QUERY_ALIASMEM 0x21
#define SAMR_OPEN_USER 0x22
+#define SAMR_QUERY_USERINFO 0x24
+#define SAMR_SET_USERINFO2 0x25
+#define SAMR_QUERY_USERGROUPS 0x27
#define SAMR_CREATE_USER 0x32
#define SAMR_SET_USERINFO 0x3A
-#define SAMR_QUERY_USERINFO 0x24
-#define SAMR_QUERY_USERGROUPS 0x27
#define SAMR_QUERY_DISPINFO 0x28
#define SAMR_GET_USRDOM_PWINFO 0x2c
@@ -141,6 +142,13 @@ typedef struct logon_hours_info
} LOGON_HRS;
+/* SAM_USER_INFO_16 */
+typedef struct sam_user_info_16
+{
+ uint16 acb_info; /* account info (ACB_xxxx bit-mask) */
+
+} SAM_USER_INFO_16;
+
/* SAM_USER_INFO_23 */
typedef struct sam_user_info_23
{
@@ -1152,6 +1160,29 @@ typedef struct r_samr_query_usergroup_info
} SAMR_R_QUERY_USERGROUPS;
+/* SAMR_Q_SET_USERINFO2 - set sam info */
+typedef struct q_samr_set_user_info2
+{
+ POLICY_HND pol; /* policy handle associated with user */
+ uint16 switch_value; /* 0x0010 */
+ uint16 switch_value2; /* 0x0010 */
+
+ union
+ {
+ SAM_USER_INFO_16 *id16; /* auth-level 0x10 */
+ void* id; /* to make typecasting easy */
+
+ } info;
+
+} SAMR_Q_SET_USERINFO2;
+
+/* SAMR_R_SET_USERINFO2 - set sam info */
+typedef struct r_samr_set_user_info2
+{
+ uint32 status; /* return status */
+
+} SAMR_R_SET_USERINFO2;
+
/* SAMR_Q_SET_USERINFO - set sam info */
typedef struct q_samr_set_user_info
{
diff --git a/source3/rpc_client/cli_samr.c b/source3/rpc_client/cli_samr.c
index d16098247f..d25b6e2305 100644
--- a/source3/rpc_client/cli_samr.c
+++ b/source3/rpc_client/cli_samr.c
@@ -307,6 +307,41 @@ BOOL get_samr_query_aliasmem(struct cli_state *cli, uint16 fnum,
/****************************************************************************
do a SAMR set user info
****************************************************************************/
+BOOL set_samr_set_userinfo2(struct cli_state *cli, uint16 fnum,
+ POLICY_HND *pol_open_domain,
+ uint32 info_level,
+ uint32 user_rid, void *usr)
+{
+ POLICY_HND pol_open_user;
+ BOOL ret = True;
+
+ if (pol_open_domain == NULL || usr == NULL) return False;
+
+ /* send open domain (on user sid) */
+ if (!samr_open_user(cli, fnum,
+ pol_open_domain,
+ 0x000601b4, user_rid,
+ &pol_open_user))
+ {
+ return False;
+ }
+
+ /* send user info query */
+ if (!samr_set_userinfo2(cli, fnum,
+ &pol_open_user,
+ info_level, usr))
+ {
+ DEBUG(5,("samr_set_userinfo: error in query user info, level 0x%x\n",
+ info_level));
+ ret = False;
+ }
+
+ return samr_close(cli, fnum,&pol_open_user) && ret;
+}
+
+/****************************************************************************
+do a SAMR set user info
+****************************************************************************/
BOOL set_samr_set_userinfo(struct cli_state *cli, uint16 fnum,
POLICY_HND *pol_open_domain,
uint32 info_level,
@@ -345,15 +380,13 @@ do a SAMR query user info
BOOL get_samr_query_userinfo(struct cli_state *cli, uint16 fnum,
POLICY_HND *pol_open_domain,
uint32 info_level,
- uint32 user_rid, SAM_USER_INFO_21 *usr)
+ uint32 user_rid, void *usr)
{
POLICY_HND pol_open_user;
BOOL ret = True;
if (pol_open_domain == NULL || usr == NULL) return False;
- bzero(usr, sizeof(*usr));
-
/* send open domain (on user sid) */
if (!samr_open_user(cli, fnum,
pol_open_domain,
@@ -366,7 +399,7 @@ BOOL get_samr_query_userinfo(struct cli_state *cli, uint16 fnum,
/* send user info query */
if (!samr_query_userinfo(cli, fnum,
&pol_open_user,
- info_level, (void*)usr))
+ info_level, usr))
{
DEBUG(5,("samr_query_userinfo: error in query user info, level 0x%x\n",
info_level));
@@ -2559,6 +2592,62 @@ BOOL samr_query_groupinfo(struct cli_state *cli, uint16 fnum,
/****************************************************************************
do a SAMR Set User Info
****************************************************************************/
+BOOL samr_set_userinfo2(struct cli_state *cli, uint16 fnum,
+ POLICY_HND *pol, uint16 switch_value,
+ void* usr)
+{
+ prs_struct data;
+ prs_struct rdata;
+
+ SAMR_Q_SET_USERINFO2 q_o;
+ BOOL valid_query = False;
+
+ DEBUG(4,("SAMR Set User Info 2. level: %d\n", switch_value));
+
+ if (pol == NULL || usr == NULL || switch_value == 0) return False;
+
+ /* create and send a MSRPC command with api SAMR_SET_USERINFO2 */
+
+ prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
+ prs_init(&rdata, 0 , 4, SAFETY_MARGIN, True );
+
+ /* store the parameters */
+ make_samr_q_set_userinfo2(&q_o, pol, switch_value, usr);
+
+ /* turn parameters into data stream */
+ samr_io_q_set_userinfo2("", &q_o, &data, 0);
+
+ /* send the data on \PIPE\ */
+ if (rpc_api_pipe_req(cli, fnum, SAMR_SET_USERINFO2, &data, &rdata))
+ {
+ SAMR_R_SET_USERINFO2 r_o;
+ BOOL p;
+
+ samr_io_r_set_userinfo2("", &r_o, &rdata, 0);
+ p = rdata.offset != 0;
+
+ if (p && r_o.status != 0)
+ {
+ /* report error code */
+ DEBUG(4,("SAMR_R_QUERY_USERINFO2: %s\n", get_nt_error_msg(r_o.status)));
+ p = False;
+ }
+
+ if (p)
+ {
+ valid_query = True;
+ }
+ }
+
+ prs_mem_free(&data );
+ prs_mem_free(&rdata );
+
+ return valid_query;
+}
+
+/****************************************************************************
+do a SAMR Set User Info
+****************************************************************************/
BOOL samr_set_userinfo(struct cli_state *cli, uint16 fnum,
POLICY_HND *pol, uint16 switch_value, void* usr)
{
diff --git a/source3/rpc_parse/parse_samr.c b/source3/rpc_parse/parse_samr.c
index 9ea66bbf4b..9f4ad7719e 100644
--- a/source3/rpc_parse/parse_samr.c
+++ b/source3/rpc_parse/parse_samr.c
@@ -4931,7 +4931,7 @@ static BOOL sam_io_user_info24(char *desc, SAM_USER_INFO_24 *usr, prs_struct *p
{
if (usr == NULL) return False;
- prs_debug(ps, depth, desc, "lsa_io_user_info");
+ prs_debug(ps, depth, desc, "sam_io_user_info24");
depth++;
prs_align(ps);
@@ -5169,11 +5169,29 @@ BOOL make_sam_user_info23A(SAM_USER_INFO_23 *usr,
/*******************************************************************
reads or writes a structure.
********************************************************************/
+static BOOL sam_io_user_info16(char *desc, SAM_USER_INFO_16 *usr, prs_struct *ps, int depth)
+{
+ if (usr == NULL) return False;
+
+ prs_debug(ps, depth, desc, "sam_io_user_info16");
+ depth++;
+
+ prs_align(ps);
+
+ prs_uint16("acb_info", ps, depth, &(usr->acb_info));
+ prs_align(ps);
+
+ return True;
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
static BOOL sam_io_user_info23(char *desc, SAM_USER_INFO_23 *usr, prs_struct *ps, int depth)
{
if (usr == NULL) return False;
- prs_debug(ps, depth, desc, "lsa_io_user_info");
+ prs_debug(ps, depth, desc, "sam_io_user_info23");
depth++;
prs_align(ps);
@@ -5364,7 +5382,7 @@ static BOOL sam_io_user_info21(char *desc, SAM_USER_INFO_21 *usr, prs_struct *p
{
if (usr == NULL) return False;
- prs_debug(ps, depth, desc, "lsa_io_user_info");
+ prs_debug(ps, depth, desc, "sam_io_user_info21");
depth++;
prs_align(ps);
@@ -5768,6 +5786,143 @@ BOOL samr_io_r_set_userinfo(char *desc, SAMR_R_SET_USERINFO *r_u, prs_struct *p
}
/*******************************************************************
+makes a SAMR_Q_SET_USERINFO2 structure.
+********************************************************************/
+BOOL make_samr_q_set_userinfo2(SAMR_Q_SET_USERINFO2 *q_u,
+ POLICY_HND *hnd,
+ uint16 switch_value, void *info)
+{
+ if (q_u == NULL || hnd == NULL) return False;
+
+ DEBUG(5,("make_samr_q_set_userinfo2\n"));
+
+ memcpy(&(q_u->pol), hnd, sizeof(q_u->pol));
+ q_u->switch_value = switch_value;
+ q_u->switch_value2 = switch_value;
+ q_u->info.id = info;
+
+ switch (switch_value)
+ {
+ case 0x10:
+ {
+ break;
+ }
+ default:
+ {
+ DEBUG(4,("make_samr_q_set_userinfo2: unsupported switch level\n"));
+ return False;
+ }
+ }
+
+ return True;
+}
+
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+BOOL samr_io_q_set_userinfo2(char *desc, SAMR_Q_SET_USERINFO2 *q_u, prs_struct *ps, int depth)
+{
+ if (q_u == NULL) return False;
+
+ prs_debug(ps, depth, desc, "samr_io_q_set_userinfo2");
+ depth++;
+
+ prs_align(ps);
+
+ smb_io_pol_hnd("pol", &(q_u->pol), ps, depth);
+ prs_align(ps);
+
+ prs_uint16("switch_value ", ps, depth, &(q_u->switch_value ));
+ prs_uint16("switch_value2", ps, depth, &(q_u->switch_value2));
+
+ prs_align(ps);
+
+ switch (q_u->switch_value)
+ {
+ case 0:
+ {
+ break;
+ }
+ case 16:
+ {
+ if (ps->io)
+ {
+ /* reading */
+ q_u->info.id = (SAM_USER_INFO_16*)Realloc(NULL,
+ sizeof(*q_u->info.id16));
+ }
+ if (q_u->info.id == NULL)
+ {
+ DEBUG(2,("samr_io_q_query_userinfo2: info pointer not initialised\n"));
+ return False;
+ }
+ sam_io_user_info16("", q_u->info.id16, ps, depth);
+ break;
+ }
+ default:
+ {
+ DEBUG(2,("samr_io_q_query_userinfo2: unknown switch level\n"));
+ break;
+ }
+
+ }
+ prs_align(ps);
+
+ if (!ps->io)
+ {
+ /* writing */
+ free_samr_q_set_userinfo2(q_u);
+ }
+
+ return True;
+}
+
+/*******************************************************************
+frees a structure.
+********************************************************************/
+void free_samr_q_set_userinfo2(SAMR_Q_SET_USERINFO2 *q_u)
+{
+ if (q_u->info.id == NULL)
+ {
+ free(q_u->info.id);
+ }
+ q_u->info.id = NULL;
+}
+
+/*******************************************************************
+makes a SAMR_R_SET_USERINFO2 structure.
+********************************************************************/
+BOOL make_samr_r_set_userinfo2(SAMR_R_SET_USERINFO2 *r_u,
+ uint32 status)
+{
+ if (r_u == NULL) return False;
+
+ DEBUG(5,("make_samr_r_set_userinfo2\n"));
+
+ r_u->status = status; /* return status */
+
+ return True;
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+BOOL samr_io_r_set_userinfo2(char *desc, SAMR_R_SET_USERINFO2 *r_u, prs_struct *ps, int depth)
+{
+ if (r_u == NULL) return False;
+
+ prs_debug(ps, depth, desc, "samr_io_r_set_userinfo2");
+ depth++;
+
+ prs_align(ps);
+
+ prs_uint32("status", ps, depth, &(r_u->status));
+
+ return True;
+}
+
+/*******************************************************************
makes a SAMR_Q_CONNECT structure.
********************************************************************/
BOOL make_samr_q_connect(SAMR_Q_CONNECT *q_u,
diff --git a/source3/rpc_server/srv_samr.c b/source3/rpc_server/srv_samr.c
index ff2f1bbb8c..4761ceb014 100644
--- a/source3/rpc_server/srv_samr.c
+++ b/source3/rpc_server/srv_samr.c
@@ -2122,6 +2122,31 @@ static BOOL set_user_info_23(SAM_USER_INFO_23 *id23, uint32 rid)
}
/*******************************************************************
+ set_user_info_16
+ ********************************************************************/
+static BOOL set_user_info_16(SAM_USER_INFO_16 *id16, uint32 rid)
+{
+ struct sam_passwd *pwd = getsam21pwrid(rid);
+ struct sam_passwd new_pwd;
+
+ if (id16 == NULL)
+ {
+ DEBUG(5, ("set_user_info_16: NULL id16\n"));
+ return False;
+ }
+ if (pwd == NULL)
+ {
+ return False;
+ }
+
+ copy_sam_passwd(&new_pwd, pwd);
+
+ new_pwd.acct_ctrl = id16->acb_info;
+
+ return mod_sam21pwd_entry(&new_pwd, True);
+}
+
+/*******************************************************************
api_samr_query_userinfo
********************************************************************/
static void api_samr_query_userinfo( pipes_struct *p, prs_struct *data, prs_struct *rdata)
@@ -2133,6 +2158,87 @@ static void api_samr_query_userinfo( pipes_struct *p, prs_struct *data, prs_stru
/*******************************************************************
+ samr_reply_set_userinfo2
+ ********************************************************************/
+static void samr_reply_set_userinfo2(SAMR_Q_SET_USERINFO2 *q_u,
+ prs_struct *rdata, uchar user_sess_key[16])
+{
+ SAMR_R_SET_USERINFO2 r_u;
+
+ uint32 status = 0x0;
+ uint32 rid = 0x0;
+
+ DEBUG(5,("samr_reply_set_userinfo2: %d\n", __LINE__));
+
+ /* search for the handle */
+ if (status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->pol)) == -1))
+ {
+ status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
+ }
+
+ /* find the user's rid */
+ if (status == 0x0 && (rid = get_lsa_policy_samr_rid(&(q_u->pol))) == 0xffffffff)
+ {
+ status = 0xC0000000 | NT_STATUS_OBJECT_TYPE_MISMATCH;
+ }
+
+ DEBUG(5,("samr_reply_set_userinfo2: rid:0x%x\n", rid));
+
+ /* ok! user info levels (there are lots: see MSDEV help), off we go... */
+ if (status == 0x0 && q_u->info.id == NULL)
+ {
+ DEBUG(5,("samr_reply_set_userinfo2: NULL info level\n"));
+ status = 0xC0000000 | NT_STATUS_INVALID_INFO_CLASS;
+ }
+
+ if (status == 0x0)
+ {
+ switch (q_u->switch_value)
+ {
+ case 16:
+ {
+ SAM_USER_INFO_16 *id16 = q_u->info.id16;
+ status = set_user_info_16(id16, rid) ? 0 : (0xC0000000 | NT_STATUS_ACCESS_DENIED);
+ break;
+ }
+ default:
+ {
+ status = 0xC0000000 | NT_STATUS_INVALID_INFO_CLASS;
+
+ break;
+ }
+ }
+ }
+
+ make_samr_r_set_userinfo2(&r_u, status);
+
+ /* store the response in the SMB stream */
+ samr_io_r_set_userinfo2("", &r_u, rdata, 0);
+
+ DEBUG(5,("samr_reply_set_userinfo2: %d\n", __LINE__));
+
+}
+
+/*******************************************************************
+ api_samr_set_userinfo2
+ ********************************************************************/
+static void api_samr_set_userinfo2( pipes_struct *p, prs_struct *data, prs_struct *rdata)
+{
+ user_struct *vuser = get_valid_user_struct(p->vuid);
+ SAMR_Q_SET_USERINFO2 q_u;
+ ZERO_STRUCT(q_u);
+
+ samr_io_q_set_userinfo2("", &q_u, data, 0);
+ samr_reply_set_userinfo2(&q_u, rdata, vuser->dc.user_sess_key);
+
+ if (q_u.info.id != NULL)
+ {
+ free(q_u.info.id);
+ }
+}
+
+
+/*******************************************************************
samr_reply_set_userinfo
********************************************************************/
static void samr_reply_set_userinfo(SAMR_Q_SET_USERINFO *q_u,
@@ -3038,6 +3144,7 @@ static struct api_struct api_samr_cmds [] =
{ "SAMR_OPEN_USER" , SAMR_OPEN_USER , api_samr_open_user },
{ "SAMR_QUERY_USERINFO" , SAMR_QUERY_USERINFO , api_samr_query_userinfo },
{ "SAMR_SET_USERINFO" , SAMR_SET_USERINFO , api_samr_set_userinfo },
+ { "SAMR_SET_USERINFO2" , SAMR_SET_USERINFO2 , api_samr_set_userinfo2 },
{ "SAMR_QUERY_DOMAIN_INFO", SAMR_QUERY_DOMAIN_INFO, api_samr_query_dom_info },
{ "SAMR_QUERY_USERGROUPS" , SAMR_QUERY_USERGROUPS , api_samr_query_usergroups },
{ "SAMR_QUERY_DISPINFO" , SAMR_QUERY_DISPINFO , api_samr_query_dispinfo },
diff --git a/source3/rpcclient/cmd_samr.c b/source3/rpcclient/cmd_samr.c
index e9314bada6..90266f0868 100644
--- a/source3/rpcclient/cmd_samr.c
+++ b/source3/rpcclient/cmd_samr.c
@@ -2573,6 +2573,162 @@ void cmd_sam_query_user(struct client_info *info)
/****************************************************************************
experimental SAM user set.
****************************************************************************/
+void cmd_sam_set_userinfo2(struct client_info *info)
+{
+ uint16 fnum;
+ fstring srv_name;
+ fstring domain;
+ fstring sid_str;
+ DOM_SID sid;
+ BOOL res = True;
+ BOOL res1 = True;
+ uint32 argc = 0;
+ char **argv = NULL;
+ uint32 cp_argc = 0;
+ char **cp_argv = NULL;
+ extern int optind;
+ int opt;
+ BOOL set_acb_bits = False;
+
+ fstring user_name;
+ fstring tmp;
+
+ char *names[1];
+ uint32 num_rids;
+ uint32 rid[MAX_LOOKUP_SIDS];
+ uint32 type[MAX_LOOKUP_SIDS];
+ POLICY_HND sam_pol;
+ POLICY_HND pol_dom;
+ SAM_USER_INFO_16 usr16;
+ uint16 acb_set = 0x0;
+
+ fstrcpy(domain, info->dom.level5_dom);
+ sid_copy(&sid, &info->dom.level5_sid);
+
+ if (sid.num_auths == 0)
+ {
+ report(out_hnd, "please use 'lsaquery' first, to ascertain the SID\n");
+ return;
+ }
+
+ /* create arguments array */
+ while (next_token(NULL, tmp, NULL, sizeof(tmp)))
+ {
+ add_chars_to_array(&argc, &argv, tmp);
+ }
+
+ cp_argc = argc;
+ cp_argv = argv;
+
+ if (cp_argc < 2)
+ {
+ report(out_hnd, "samuserset2 <name> [-s <acb_bits>]\n");
+ return;
+ }
+
+ safe_strcpy(user_name, cp_argv[0], sizeof(user_name));
+
+ cp_argc--;
+ cp_argv++;
+
+ optind = -1;
+ while ((opt = getopt(cp_argc, cp_argv,"s:")) != EOF)
+ {
+ switch (opt)
+ {
+ case 's':
+ {
+ set_acb_bits = True;
+ acb_set = get_number(optarg);
+ break;
+ }
+ }
+ }
+
+ fstrcpy(srv_name, "\\\\");
+ fstrcat(srv_name, info->dest_host);
+ strupper(srv_name);
+
+ sid_to_string(sid_str, &sid);
+
+ report(out_hnd, "SAM Set User Info: %s\n", user_name);
+
+ /* open SAMR session. negotiate credentials */
+ res = res ? cli_nt_session_open(smb_cli, PIPE_SAMR, &fnum) : False;
+
+ /* establish a connection. */
+ res = res ? samr_connect(smb_cli, fnum,
+ srv_name, 0x02000000,
+ &sam_pol) : False;
+
+ /* connect to the domain */
+ res = res ? samr_open_domain(smb_cli, fnum,
+ &sam_pol, 0x02000000, &sid,
+ &pol_dom) : False;
+
+ /* look up user rid */
+ names[0] = user_name;
+ res1 = res ? samr_query_lookup_names(smb_cli, fnum,
+ &pol_dom, 0x3e8,
+ 1, names,
+ &num_rids, rid, type) : False;
+
+ /* send set user info */
+ if (res1 && num_rids == 1 && get_samr_query_userinfo(smb_cli, fnum,
+ &pol_dom,
+ 0x10, rid[0],
+ (void*)&usr16))
+ {
+ void *usr = NULL;
+ uint32 switch_value = 0;
+
+ if (set_acb_bits)
+ {
+ usr16.acb_info |= acb_set;
+ }
+
+ if (True)
+ {
+ SAM_USER_INFO_16 *p = malloc(sizeof(SAM_USER_INFO_16));
+ p->acb_info = usr16.acb_info;
+
+ usr = (void*)p;
+ switch_value = 16;
+ }
+
+ if (usr != NULL)
+ {
+ res1 = set_samr_set_userinfo2(smb_cli, fnum,
+ &pol_dom,
+ switch_value, rid[0], usr);
+ }
+ }
+ res = res ? samr_close(smb_cli, fnum,
+ &sam_pol) : False;
+
+ res = res ? samr_close(smb_cli, fnum,
+ &pol_dom) : False;
+
+ /* close the session */
+ cli_nt_session_close(smb_cli, fnum);
+
+ if (res1)
+ {
+ report(out_hnd, "Set User Info: OK\n");
+ DEBUG(5,("cmd_sam_query_user: succeeded\n"));
+ }
+ else
+ {
+ report(out_hnd, "Set User Info: Failed\n");
+ DEBUG(5,("cmd_sam_query_user: failed\n"));
+ }
+
+ free_char_array(argc, argv);
+}
+
+/****************************************************************************
+experimental SAM user set.
+****************************************************************************/
void cmd_sam_set_userinfo(struct client_info *info)
{
uint16 fnum;
diff --git a/source3/rpcclient/rpcclient.c b/source3/rpcclient/rpcclient.c
index 6caefa06b2..1103a76d91 100644
--- a/source3/rpcclient/rpcclient.c
+++ b/source3/rpcclient/rpcclient.c
@@ -442,6 +442,12 @@ commands[] =
{COMPL_NONE, COMPL_NONE}
},
{
+ "samuserset2",
+ cmd_sam_set_userinfo2,
+ "<username> [-s acb_bits] SAM User Set Info 2 (experimental!)",
+ {COMPL_SAMUSR, COMPL_NONE}
+ },
+ {
"samuserset",
cmd_sam_set_userinfo,
"<username> [-p password] SAM User Set Info (experimental!)",