From d9cc4c39504534da0f4cd2569c724de4909ebd79 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Wed, 1 Dec 1999 18:47:29 +0000 Subject: improving createuser account command to be able to add workstations and then set a default random password. (This used to be commit 7846818432a93295651c8c67445a2d6a0f3b21d8) --- source3/include/proto.h | 16 ++++--- source3/include/smb_macros.h | 9 ++-- source3/rpc_client/cli_connect.c | 31 ++++++++++++ source3/rpc_client/cli_samr.c | 16 ++++--- source3/rpc_client/msrpc_samr.c | 100 ++++++++++++++++++++++++++++++++++++--- source3/rpc_parse/parse_samr.c | 19 ++++---- source3/rpcclient/cmd_samr.c | 5 +- 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 @@ -304,6 +304,21 @@ BOOL cli_pol_link(POLICY_HND *to, const POLICY_HND *from) return register_policy_hnd(to) && set_policy_con(to, con, NULL); } +/**************************************************************************** +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. @@ -343,6 +358,22 @@ BOOL cli_con_get_srvname(struct cli_connection *con, char *srv_name) return True; } +/**************************************************************************** +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. 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; -- cgit