summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/Makefile.in1
-rw-r--r--source3/include/proto.h265
-rw-r--r--source3/lib/sids.c271
-rw-r--r--source3/lib/util_pwdb.c2
-rw-r--r--source3/lib/util_sid.c296
-rw-r--r--source3/rpc_client/cli_lsarpc.c179
-rw-r--r--source3/rpc_client/cli_samr.c449
-rw-r--r--source3/rpc_client/msrpc_samr.c1427
-rw-r--r--source3/rpcclient/cmd_samr.c934
9 files changed, 2078 insertions, 1746 deletions
diff --git a/source3/Makefile.in b/source3/Makefile.in
index 8e04fa8ff7..acf20c4146 100644
--- a/source3/Makefile.in
+++ b/source3/Makefile.in
@@ -166,6 +166,7 @@ RPC_CLIENT_OBJ = \
rpc_client/cli_srvsvc.o \
rpc_client/cli_svcctl.o \
rpc_client/cli_samr.o \
+ rpc_client/msrpc_samr.o \
rpc_client/cli_atsvc.o \
rpc_client/cli_eventlog.o \
libsmb/clienttrust.o
diff --git a/source3/include/proto.h b/source3/include/proto.h
index 2b2a85ed4e..e56cfbee48 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -297,9 +297,8 @@ char *rep_inet_ntoa(struct in_addr ip);
void get_sam_domain_name(void);
BOOL get_member_domain_sid(void);
-BOOL get_domain_sids(DOM_SID *sid3, DOM_SID *sid5, char *servers);
void generate_wellknown_sids(void);
-BOOL generate_sam_sid(char *domain_name);
+BOOL generate_sam_sid(char *domain_name, DOM_SID *sid);
BOOL map_domain_name_to_sid(DOM_SID *sid, char **nt_domain);
BOOL map_domain_sid_to_name(DOM_SID *sid, char *nt_domain);
BOOL split_domain_name(const char *fullname, char *domain, char *name);
@@ -560,6 +559,9 @@ BOOL sid_front_equal(const DOM_SID *sid1, const DOM_SID *sid2);
BOOL sid_equal(const DOM_SID *sid1, const DOM_SID *sid2);
int sid_size(const DOM_SID *sid);
DOM_SID *sid_dup(const DOM_SID *src);
+BOOL read_sid(char *domain_name, DOM_SID *sid);
+BOOL write_sid(char *domain_name, DOM_SID *sid);
+BOOL create_new_sid(DOM_SID *sid);
/*The following definitions come from lib/util_sock.c */
@@ -1779,6 +1781,11 @@ BOOL cli_nt_logoff(struct cli_state *cli, uint16 fnum, NET_ID_INFO_CTR *ctr);
/*The following definitions come from rpc_client/cli_lsarpc.c */
+BOOL get_domain_sids(const char *myname,
+ DOM_SID *sid3, DOM_SID *sid5, char *servers);
+BOOL get_trust_sid_and_domain(const char* myname, char *server,
+ DOM_SID *sid,
+ char *domain, size_t len);
BOOL lsa_open_policy(struct cli_state *cli, uint16 fnum,
const char *server_name, POLICY_HND *hnd,
BOOL sec_qos);
@@ -1913,55 +1920,6 @@ BOOL do_reg_shutdown(struct cli_state *cli, uint16 fnum,
/*The following definitions come from rpc_client/cli_samr.c */
-BOOL create_samr_domain_user(struct cli_state *cli, uint16 fnum,
- POLICY_HND *pol_open_domain,
- const char *acct_name, uint16 acb_info,
- uint32 *rid);
-BOOL create_samr_domain_alias(struct cli_state *cli, uint16 fnum,
- POLICY_HND *pol_open_domain,
- const char *acct_name, const char *acct_desc,
- uint32 *rid);
-BOOL create_samr_domain_group(struct cli_state *cli, uint16 fnum,
- POLICY_HND *pol_open_domain,
- const char *acct_name, const char *acct_desc,
- uint32 *rid);
-BOOL get_samr_query_usergroups(struct cli_state *cli, uint16 fnum,
- const POLICY_HND *pol_open_domain,
- uint32 user_rid,
- uint32 *num_groups, DOM_GID **gid);
-BOOL delete_samr_dom_group(struct cli_state *cli, uint16 fnum,
- POLICY_HND *pol_open_domain,
- uint32 group_rid);
-BOOL get_samr_query_groupmem(struct cli_state *cli, uint16 fnum,
- const POLICY_HND *pol_open_domain,
- uint32 group_rid, uint32 *num_mem,
- uint32 **rid, uint32 **attr);
-BOOL delete_samr_dom_alias(struct cli_state *cli, uint16 fnum,
- POLICY_HND *pol_open_domain,
- uint32 alias_rid);
-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,
- uint32 user_rid, void *usr);
-BOOL get_samr_query_userinfo(struct cli_state *cli, uint16 fnum,
- POLICY_HND *pol_open_domain,
- uint32 info_level,
- 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,
- uint32 group_rid, GROUP_INFO_CTR *ctr);
-BOOL get_samr_query_aliasinfo(struct cli_state *cli, uint16 fnum,
- const POLICY_HND *pol_open_domain,
- uint32 info_level,
- uint32 alias_rid, ALIAS_INFO_CTR *ctr);
BOOL samr_chgpasswd_user(struct cli_state *cli, uint16 fnum,
char *srv_name, char *user_name,
char nt_newpass[516], uchar nt_oldhash[16],
@@ -2173,6 +2131,151 @@ BOOL do_wks_query_info(struct cli_state *cli, uint16 fnum,
char *server_name, uint32 switch_value,
WKS_INFO_100 *wks100);
+/*The following definitions come from rpc_client/msrpc_samr.c */
+
+BOOL req_user_info(struct cli_state *cli, uint16 fnum,
+ POLICY_HND *pol_dom,
+ const char *domain,
+ const DOM_SID *sid,
+ uint32 user_rid,
+ USER_INFO_FN(usr_inf));
+uint32 sam_query_usergroups(struct cli_state *cli, uint16 fnum,
+ const POLICY_HND *pol_dom,
+ const char *domain,
+ const DOM_SID *sid,
+ uint32 user_rid,
+ const char *user_name,
+ uint32 *num_groups,
+ DOM_GID **gid,
+ char ***name,
+ uint32 **type,
+ USER_MEM_FN(usr_mem));
+int msrpc_sam_enum_users(struct cli_state *cli,
+ const char* domain,
+ const DOM_SID *sid1,
+ const char* srv_name,
+ struct acct_info **sam,
+ uint32 *num_sam_entries,
+ USER_FN(usr_fn),
+ USER_INFO_FN(usr_inf_fn),
+ USER_MEM_FN(usr_grp_fn),
+ USER_MEM_FN(usr_als_fn));
+BOOL sam_query_dominfo(struct cli_state *cli,
+ const DOM_SID *sid1,
+ uint32 switch_value, SAM_UNK_CTR *ctr);
+BOOL query_aliasinfo(struct cli_state *cli, uint16 fnum,
+ const POLICY_HND *pol_dom,
+ const char *domain,
+ const DOM_SID *sid,
+ uint32 alias_rid,
+ ALIAS_INFO_FN(grp_inf));
+BOOL sam_query_aliasmem(struct cli_state *cli, uint16 fnum,
+ const POLICY_HND *pol_dom,
+ uint32 alias_rid,
+ uint32 *num_names,
+ DOM_SID ***sids,
+ char ***name,
+ uint8 **type);
+BOOL req_aliasmem_info(struct cli_state *cli, uint16 fnum,
+ const POLICY_HND *pol_dom,
+ const char *domain,
+ const DOM_SID *sid,
+ uint32 alias_rid,
+ const char *alias_name,
+ ALIAS_MEM_FN(als_mem));
+BOOL sam_query_groupmem(struct cli_state *cli, uint16 fnum,
+ const POLICY_HND *pol_dom,
+ uint32 group_rid,
+ uint32 *num_names,
+ uint32 **rid_mem,
+ char ***name,
+ uint32 **type);
+BOOL query_groupinfo(struct cli_state *cli, uint16 fnum,
+ const POLICY_HND *pol_dom,
+ const char *domain,
+ const DOM_SID *sid,
+ uint32 group_rid,
+ GROUP_INFO_FN(grp_inf));
+BOOL req_groupmem_info(struct cli_state *cli, uint16 fnum,
+ const POLICY_HND *pol_dom,
+ const char *domain,
+ const DOM_SID *sid,
+ uint32 group_rid,
+ const char *group_name,
+ GROUP_MEM_FN(grp_mem));
+uint32 msrpc_sam_enum_domains(struct cli_state *cli,
+ const char* srv_name,
+ struct acct_info **sam,
+ uint32 *num_sam_entries,
+ DOMAIN_FN(dom_fn));
+uint32 msrpc_sam_enum_groups(struct cli_state *cli,
+ const char* domain,
+ const DOM_SID *sid1,
+ const char* srv_name,
+ struct acct_info **sam,
+ uint32 *num_sam_entries,
+ GROUP_FN(grp_fn),
+ GROUP_INFO_FN(grp_inf_fn),
+ GROUP_MEM_FN(grp_mem_fn));
+uint32 msrpc_sam_enum_aliases(struct cli_state *cli,
+ const char* domain,
+ const DOM_SID *sid1,
+ const char* srv_name,
+ struct acct_info **sam,
+ uint32 *num_sam_entries,
+ ALIAS_FN(als_fn),
+ ALIAS_INFO_FN(als_inf_fn),
+ ALIAS_MEM_FN(als_mem_fn));
+BOOL create_samr_domain_user(struct cli_state *cli, uint16 fnum,
+ POLICY_HND *pol_open_domain,
+ const char *acct_name, uint16 acb_info,
+ uint32 *rid);
+BOOL create_samr_domain_alias(struct cli_state *cli, uint16 fnum,
+ POLICY_HND *pol_open_domain,
+ const char *acct_name, const char *acct_desc,
+ uint32 *rid);
+BOOL create_samr_domain_group(struct cli_state *cli, uint16 fnum,
+ POLICY_HND *pol_open_domain,
+ const char *acct_name, const char *acct_desc,
+ uint32 *rid);
+BOOL get_samr_query_usergroups(struct cli_state *cli, uint16 fnum,
+ const POLICY_HND *pol_open_domain,
+ uint32 user_rid,
+ uint32 *num_groups, DOM_GID **gid);
+BOOL delete_samr_dom_group(struct cli_state *cli, uint16 fnum,
+ POLICY_HND *pol_open_domain,
+ uint32 group_rid);
+BOOL get_samr_query_groupmem(struct cli_state *cli, uint16 fnum,
+ const POLICY_HND *pol_open_domain,
+ uint32 group_rid, uint32 *num_mem,
+ uint32 **rid, uint32 **attr);
+BOOL delete_samr_dom_alias(struct cli_state *cli, uint16 fnum,
+ POLICY_HND *pol_open_domain,
+ uint32 alias_rid);
+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,
+ uint32 user_rid, void *usr);
+BOOL get_samr_query_userinfo(struct cli_state *cli, uint16 fnum,
+ POLICY_HND *pol_open_domain,
+ uint32 info_level,
+ 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,
+ uint32 group_rid, GROUP_INFO_CTR *ctr);
+BOOL get_samr_query_aliasinfo(struct cli_state *cli, uint16 fnum,
+ const POLICY_HND *pol_open_domain,
+ uint32 info_level,
+ uint32 alias_rid, ALIAS_INFO_CTR *ctr);
+
/*The following definitions come from rpc_parse/parse_at.c */
BOOL make_at_q_add_job(AT_Q_ADD_JOB *q_a, char *server,
@@ -3460,66 +3563,6 @@ void cmd_reg_shutdown(struct client_info *info);
/*The following definitions come from rpcclient/cmd_samr.c */
-uint32 sam_query_usergroups(struct cli_state *cli, uint16 fnum,
- const POLICY_HND *pol_dom,
- const char *domain,
- const DOM_SID *sid,
- uint32 user_rid,
- const char *user_name,
- uint32 *num_groups,
- DOM_GID **gid,
- char ***name,
- uint32 **type,
- USER_MEM_FN(usr_mem));
-int msrpc_sam_enum_users(struct cli_state *cli,
- const char* domain,
- const DOM_SID *sid1,
- const char* srv_name,
- struct acct_info **sam,
- uint32 *num_sam_entries,
- USER_FN(usr_fn),
- USER_INFO_FN(usr_inf_fn),
- USER_MEM_FN(usr_grp_fn),
- USER_MEM_FN(usr_als_fn));
-BOOL sam_query_dominfo(struct client_info *info, const DOM_SID *sid1,
- uint32 switch_value, SAM_UNK_CTR *ctr);
-BOOL sam_query_aliasmem(struct cli_state *cli, uint16 fnum,
- const POLICY_HND *pol_dom,
- uint32 alias_rid,
- uint32 *num_names,
- DOM_SID ***sids,
- char ***name,
- uint8 **type);
-BOOL sam_query_groupmem(struct cli_state *cli, uint16 fnum,
- const POLICY_HND *pol_dom,
- uint32 group_rid,
- uint32 *num_names,
- uint32 **rid_mem,
- char ***name,
- uint32 **type);
-uint32 msrpc_sam_enum_domains(struct cli_state *cli,
- const char* srv_name,
- struct acct_info **sam,
- uint32 *num_sam_entries,
- DOMAIN_FN(dom_fn));
-uint32 msrpc_sam_enum_groups(struct cli_state *cli,
- const char* domain,
- const DOM_SID *sid1,
- const char* srv_name,
- struct acct_info **sam,
- uint32 *num_sam_entries,
- GROUP_FN(grp_fn),
- GROUP_INFO_FN(grp_inf_fn),
- GROUP_MEM_FN(grp_mem_fn));
-uint32 msrpc_sam_enum_aliases(struct cli_state *cli,
- const char* domain,
- const DOM_SID *sid1,
- const char* srv_name,
- struct acct_info **sam,
- uint32 *num_sam_entries,
- ALIAS_FN(als_fn),
- ALIAS_INFO_FN(als_inf_fn),
- ALIAS_MEM_FN(als_mem_fn));
void cmd_sam_ntchange_pwd(struct client_info *info);
void cmd_sam_test(struct client_info *info);
void cmd_sam_lookup_domain(struct client_info *info);
diff --git a/source3/lib/sids.c b/source3/lib/sids.c
index 4d83adc36d..052c05cb01 100644
--- a/source3/lib/sids.c
+++ b/source3/lib/sids.c
@@ -87,39 +87,6 @@ sid_name_map[] =
};
/****************************************************************************
- Read the machine SID from a file.
-****************************************************************************/
-
-static BOOL read_sid_from_file(int fd, char *sid_file)
-{
- fstring fline;
- fstring sid_str;
-
- memset(fline, '\0', sizeof(fline));
-
- if (read(fd, fline, sizeof(fline) -1 ) < 0) {
- DEBUG(0,("unable to read file %s. Error was %s\n",
- sid_file, strerror(errno) ));
- return False;
- }
-
- /*
- * Convert to the machine SID.
- */
-
- fline[sizeof(fline)-1] = '\0';
- if (!string_to_sid( &global_sam_sid, fline)) {
- DEBUG(0,("unable to generate machine SID.\n"));
- return False;
- }
-
- sid_to_string(sid_str, &global_sam_sid);
- DEBUG(5,("read_sid_from_file: sid %s\n", sid_str));
-
- return True;
-}
-
-/****************************************************************************
sets up the name associated with the SAM database for which we are responsible
****************************************************************************/
void get_sam_domain_name(void)
@@ -175,99 +142,6 @@ BOOL get_member_domain_sid(void)
return get_domain_sids(NULL, &global_member_sid, lp_passwordserver());
}
-/****************************************************************************
- obtain the sid from the PDC. do some verification along the way...
-****************************************************************************/
-BOOL get_domain_sids(DOM_SID *sid3, DOM_SID *sid5, char *servers)
-{
- uint16 nt_pipe_fnum;
- POLICY_HND pol;
- fstring srv_name;
- struct cli_state cli;
- BOOL res = True;
- fstring dom3;
- fstring dom5;
-
- if (sid3 == NULL && sid5 == NULL)
- {
- /* don't waste my time... */
- return False;
- }
-
- if (!cli_connect_serverlist(&cli, servers))
- {
- DEBUG(0,("get_domain_sids: unable to initialise client connection.\n"));
- return False;
- }
-
- /*
- * Ok - we have an anonymous connection to the IPC$ share.
- * Now start the NT Domain stuff :-).
- */
-
- fstrcpy(dom3, "");
- fstrcpy(dom5, "");
- if (sid3 != NULL)
- {
- ZERO_STRUCTP(sid3);
- }
- if (sid5 != NULL)
- {
- ZERO_STRUCTP(sid5);
- }
-
- fstrcpy(srv_name, "\\\\");
- fstrcat(srv_name, global_myname);
- strupper(srv_name);
-
- /* open LSARPC session. */
- res = res ? cli_nt_session_open(&cli, PIPE_LSARPC, &nt_pipe_fnum) : False;
-
- /* lookup domain controller; receive a policy handle */
- res = res ? lsa_open_policy(&cli, nt_pipe_fnum, srv_name, &pol, False) : False;
-
- if (sid3 != NULL)
- {
- /* send client info query, level 3. receive domain name and sid */
- res = res ? lsa_query_info_pol(&cli, nt_pipe_fnum, &pol, 3, dom3, sid3) : False;
- }
-
- if (sid5 != NULL)
- {
- /* send client info query, level 5. receive domain name and sid */
- res = res ? lsa_query_info_pol(&cli, nt_pipe_fnum, &pol, 5, dom5, sid5) : False;
- }
-
- /* close policy handle */
- res = res ? lsa_close(&cli, nt_pipe_fnum, &pol) : False;
-
- /* close the session */
- cli_nt_session_close(&cli, nt_pipe_fnum);
- cli_ulogoff(&cli);
- cli_shutdown(&cli);
-
- if (res)
- {
- pstring sid;
- DEBUG(2,("LSA Query Info Policy\n"));
- if (sid3 != NULL)
- {
- sid_to_string(sid, sid3);
- DEBUG(2,("Domain Member - Domain: %s SID: %s\n", dom3, sid));
- }
- if (sid5 != NULL)
- {
- sid_to_string(sid, sid5);
- DEBUG(2,("Domain Controller - Domain: %s SID: %s\n", dom5, sid));
- }
- }
- else
- {
- DEBUG(1,("lsa query info failed\n"));
- }
-
- return res;
-}
/****************************************************************************
creates some useful well known sids
@@ -284,17 +158,12 @@ void generate_wellknown_sids(void)
Generate the global machine sid. Look for the DOMAINNAME.SID file first, if
not found then look in smb.conf and use it to create the DOMAINNAME.SID file.
****************************************************************************/
-BOOL generate_sam_sid(char *domain_name)
+BOOL generate_sam_sid(char *domain_name, DOM_SID *sid)
{
- int fd;
- int i;
char *p;
pstring sid_file;
pstring machine_sid_file;
- fstring sid_string;
fstring file_name;
- SMB_STRUCT_STAT st;
- uchar raw_sid_data[12];
pstrcpy(sid_file, lp_smb_passwd_file());
@@ -341,131 +210,30 @@ BOOL generate_sam_sid(char *domain_name)
}
}
- if ((fd = sys_open(sid_file, O_RDWR | O_CREAT, 0644)) == -1) {
- DEBUG(0,("unable to open or create file %s. Error was %s\n",
- sid_file, strerror(errno) ));
- return False;
- }
-
- /*
- * Check if the file contains data.
- */
-
- if (sys_fstat( fd, &st) < 0) {
- DEBUG(0,("unable to stat file %s. Error was %s\n",
- sid_file, strerror(errno) ));
- close(fd);
- return False;
- }
-
- if (st.st_size > 0) {
- /*
- * We have a valid SID - read it.
- */
- if (!read_sid_from_file( fd, sid_file)) {
- DEBUG(0,("unable to read file %s. Error was %s\n",
- sid_file, strerror(errno) ));
- close(fd);
- return False;
- }
- close(fd);
+ /* attempt to read the SID from the file */
+ if (read_sid(domain_name, sid))
+ {
return True;
- }
-
- /*
- * Generate the new sid data & turn it into a string.
- */
- generate_random_buffer( raw_sid_data, 12, True);
-
- fstrcpy( sid_string, "S-1-5-21");
- for( i = 0; i < 3; i++) {
- fstring tmp_string;
- slprintf( tmp_string, sizeof(tmp_string) - 1, "-%u", IVAL(raw_sid_data, i*4));
- fstrcat( sid_string, tmp_string);
}
-
- fstrcat(sid_string, "\n");
-
- /*
- * Ensure our new SID is valid.
- */
-
- if (!string_to_sid( &global_sam_sid, sid_string)) {
- DEBUG(0,("unable to generate machine SID.\n"));
- return False;
- }
- /*
- * Do an exclusive blocking lock on the file.
- */
-
- if (!do_file_lock( fd, 60, F_WRLCK)) {
- DEBUG(0,("unable to lock file %s. Error was %s\n",
- sid_file, strerror(errno) ));
- close(fd);
- return False;
- }
-
- /*
- * At this point we have a blocking lock on the SID
- * file - check if in the meantime someone else wrote
- * SID data into the file. If so - they were here first,
- * use their data.
- */
-
- if (sys_fstat( fd, &st) < 0) {
- DEBUG(0,("unable to stat file %s. Error was %s\n",
- sid_file, strerror(errno) ));
- close(fd);
+ if (!create_new_sid(sid))
+ {
return False;
- }
+ }
+ /* attempt to read the SID from the file */
+ if (!write_sid(domain_name, sid))
+ {
+ return True;
+ }
- if (st.st_size > 0) {
- /*
- * Unlock as soon as possible to reduce
- * contention on the exclusive lock.
- */
- do_file_lock( fd, 60, F_UNLCK);
-
- /*
- * We have a valid SID - read it.
- */
-
- if (!read_sid_from_file( fd, sid_file)) {
- DEBUG(0,("unable to read file %s. Error was %s\n",
- sid_file, strerror(errno) ));
- close(fd);
- return False;
- }
- close(fd);
+ /* during the attempt to write, someone else wrote? */
+
+ /* attempt to read the SID from the file */
+ if (read_sid(domain_name, sid))
+ {
return True;
- }
-
- /*
- * The file is still empty and we have an exlusive lock on it.
- * Write out out SID data into the file.
- */
-
- if (fchmod(fd, 0644) < 0) {
- DEBUG(0,("unable to set correct permissions on file %s. \
-Error was %s\n", sid_file, strerror(errno) ));
- close(fd);
- return False;
- }
-
- if (write( fd, sid_string, strlen(sid_string)) != strlen(sid_string)) {
- DEBUG(0,("unable to write file %s. Error was %s\n",
- sid_file, strerror(errno) ));
- close(fd);
- return False;
- }
-
- /*
- * Unlock & exit.
- */
-
- do_file_lock( fd, 60, F_UNLCK);
- close(fd);
+ }
+
return True;
}
@@ -630,3 +398,4 @@ BOOL enumdomains(char ***doms, uint32 *num_entries)
return True;
}
+
diff --git a/source3/lib/util_pwdb.c b/source3/lib/util_pwdb.c
index 0bf0cd9c4f..f27cce8fba 100644
--- a/source3/lib/util_pwdb.c
+++ b/source3/lib/util_pwdb.c
@@ -616,7 +616,7 @@ BOOL pwdb_initialise(BOOL is_server)
if (is_server)
{
- if (!generate_sam_sid(global_sam_name))
+ if (!generate_sam_sid(global_sam_name, &global_sam_sid))
{
DEBUG(0,("ERROR: Samba cannot create a SAM SID for its domain (%s).\n",
global_sam_name));
diff --git a/source3/lib/util_sid.c b/source3/lib/util_sid.c
index 295fd0efac..b497a1e455 100644
--- a/source3/lib/util_sid.c
+++ b/source3/lib/util_sid.c
@@ -245,3 +245,299 @@ DOM_SID *sid_dup(const DOM_SID *src)
return dst;
}
+
+
+/****************************************************************************
+ Read a SID from a file.
+****************************************************************************/
+
+static BOOL read_sid_from_file(int fd, char *sid_file, DOM_SID *sid)
+{
+ fstring fline;
+ fstring sid_str;
+
+ memset(fline, '\0', sizeof(fline));
+
+ if (read(fd, fline, sizeof(fline) -1 ) < 0) {
+ DEBUG(0,("unable to read file %s. Error was %s\n",
+ sid_file, strerror(errno) ));
+ return False;
+ }
+
+ /*
+ * Convert to the machine SID.
+ */
+
+ fline[sizeof(fline)-1] = '\0';
+ if (!string_to_sid(sid, fline)) {
+ DEBUG(0,("unable to generate machine SID.\n"));
+ return False;
+ }
+
+ sid_to_string(sid_str, sid);
+ DEBUG(5,("read_sid_from_file: sid %s\n", sid_str));
+
+ return True;
+}
+
+/****************************************************************************
+ Generate the global machine sid. Look for the DOMAINNAME.SID file first, if
+ not found then look in smb.conf and use it to create the DOMAINNAME.SID file.
+****************************************************************************/
+BOOL read_sid(char *domain_name, DOM_SID *sid)
+{
+ int fd;
+ char *p;
+ pstring sid_file;
+ fstring sid_string;
+ fstring file_name;
+ SMB_STRUCT_STAT st;
+
+ pstrcpy(sid_file, lp_smb_passwd_file());
+ sid_to_string(sid_string, sid);
+
+ DEBUG(10,("read_sid: Domain: %s SID: %s\n", domain_name, sid_string));
+ fstrcat(sid_string, "\n");
+
+ if (sid_file[0] == 0)
+ {
+ DEBUG(0,("cannot find smb passwd file\n"));
+ return False;
+ }
+
+ p = strrchr(sid_file, '/');
+ if (p != NULL)
+ {
+ *++p = '\0';
+ }
+
+ if (!directory_exist(sid_file, NULL))
+ {
+ if (mkdir(sid_file, 0700) != 0)
+ {
+ DEBUG(0,("can't create private directory %s : %s\n",
+ sid_file, strerror(errno)));
+ return False;
+ }
+ }
+
+ slprintf(file_name, sizeof(file_name)-1, "%s.SID", domain_name);
+ strupper(file_name);
+ pstrcat(sid_file, file_name);
+
+ if ((fd = sys_open(sid_file, O_RDWR | O_CREAT, 0644)) == -1) {
+ DEBUG(0,("unable to open or create file %s. Error was %s\n",
+ sid_file, strerror(errno) ));
+ return False;
+ }
+
+ /*
+ * Check if the file contains data.
+ */
+
+ if (sys_fstat(fd, &st) < 0) {
+ DEBUG(0,("unable to stat file %s. Error was %s\n",
+ sid_file, strerror(errno) ));
+ close(fd);
+ return False;
+ }
+
+ if (st.st_size == 0)
+ {
+ close(fd);
+ return False;
+ }
+
+ /*
+ * We have a valid SID - read it.
+ */
+
+ if (!read_sid_from_file(fd, sid_file, sid))
+ {
+ DEBUG(0,("unable to read file %s. Error was %s\n",
+ sid_file, strerror(errno) ));
+ close(fd);
+ return False;
+ }
+ close(fd);
+ return True;
+}
+
+
+/****************************************************************************
+ Generate the global machine sid. Look for the DOMAINNAME.SID file first, if
+ not found then look in smb.conf and use it to create the DOMAINNAME.SID file.
+****************************************************************************/
+BOOL write_sid(char *domain_name, DOM_SID *sid)
+{
+ int fd;
+ char *p;
+ pstring sid_file;
+ fstring sid_string;
+ fstring file_name;
+ SMB_STRUCT_STAT st;
+
+ pstrcpy(sid_file, lp_smb_passwd_file());
+ sid_to_string(sid_string, sid);
+
+ DEBUG(10,("write_sid: Domain: %s SID: %s\n", domain_name, sid_string));
+ fstrcat(sid_string, "\n");
+
+ if (sid_file[0] == 0)
+ {
+ DEBUG(0,("cannot find smb passwd file\n"));
+ return False;
+ }
+
+ p = strrchr(sid_file, '/');
+ if (p != NULL)
+ {
+ *++p = '\0';
+ }
+
+ if (!directory_exist(sid_file, NULL)) {
+ if (mkdir(sid_file, 0700) != 0) {
+ DEBUG(0,("can't create private directory %s : %s\n",
+ sid_file, strerror(errno)));
+ return False;
+ }
+ }
+
+ slprintf(file_name, sizeof(file_name)-1, "%s.SID", domain_name);
+ strupper(file_name);
+ pstrcat(sid_file, file_name);
+
+ if ((fd = sys_open(sid_file, O_RDWR | O_CREAT, 0644)) == -1) {
+ DEBUG(0,("unable to open or create file %s. Error was %s\n",
+ sid_file, strerror(errno) ));
+ return False;
+ }
+
+ /*
+ * Check if the file contains data.
+ */
+
+ if (sys_fstat(fd, &st) < 0) {
+ DEBUG(0,("unable to stat file %s. Error was %s\n",
+ sid_file, strerror(errno) ));
+ close(fd);
+ return False;
+ }
+
+ if (st.st_size > 0)
+ {
+ /*
+ * We have a valid SID already.
+ */
+ close(fd);
+ DEBUG(0,("SID file %s already exists\n", sid_file));
+ return False;
+ }
+
+ if (!do_file_lock(fd, 60, F_WRLCK))
+ {
+ DEBUG(0,("unable to lock file %s. Error was %s\n",
+ sid_file, strerror(errno) ));
+ close(fd);
+ return False;
+ }
+
+ /*
+ * At this point we have a blocking lock on the SID
+ * file - check if in the meantime someone else wrote
+ * SID data into the file. If so - they were here first,
+ * use their data.
+ */
+
+ if (sys_fstat(fd, &st) < 0)
+ {
+ DEBUG(0,("unable to stat file %s. Error was %s\n",
+ sid_file, strerror(errno) ));
+ close(fd);
+ return False;
+ }
+
+ if (st.st_size > 0)
+ {
+ /*
+ * Unlock as soon as possible to reduce
+ * contention on the exclusive lock.
+ */
+ do_file_lock(fd, 60, F_UNLCK);
+
+ /*
+ * We have a valid SID already.
+ */
+
+ DEBUG(0,("SID file %s already exists\n", sid_file));
+ close(fd);
+ return False;
+ }
+
+ /*
+ * The file is still empty and we have an exlusive lock on it.
+ * Write out out SID data into the file.
+ */
+
+ if (fchmod(fd, 0644) < 0)
+ {
+ DEBUG(0,("unable to set correct permissions on file %s. \
+Error was %s\n", sid_file, strerror(errno) ));
+ close(fd);
+ return False;
+ }
+
+ if (write(fd, sid_string, strlen(sid_string)) != strlen(sid_string))
+ {
+ DEBUG(0,("unable to write file %s. Error was %s\n",
+ sid_file, strerror(errno) ));
+ close(fd);
+ return False;
+ }
+
+ /*
+ * Unlock & exit.
+ */
+
+ do_file_lock(fd, 60, F_UNLCK);
+ close(fd);
+ return True;
+}
+
+/****************************************************************************
+create a random SID.
+****************************************************************************/
+BOOL create_new_sid(DOM_SID *sid)
+{
+ uchar raw_sid_data[12];
+ fstring sid_string;
+ int i;
+
+ /*
+ * Generate the new sid data & turn it into a string.
+ */
+ generate_random_buffer(raw_sid_data, 12, True);
+
+ fstrcpy(sid_string, "S-1-5-21");
+ for(i = 0; i < 3; i++)
+ {
+ fstring tmp_string;
+ slprintf(tmp_string, sizeof(tmp_string) - 1, "-%u", IVAL(raw_sid_data, i*4));
+ fstrcat(sid_string, tmp_string);
+ }
+
+ fstrcat(sid_string, "\n");
+
+ /*
+ * Ensure our new SID is valid.
+ */
+
+ if (!string_to_sid(sid, sid_string))
+ {
+ DEBUG(0,("unable to generate machine SID.\n"));
+ return False;
+ }
+
+ return True;
+}
+
diff --git a/source3/rpc_client/cli_lsarpc.c b/source3/rpc_client/cli_lsarpc.c
index ce11999955..ebda7d8708 100644
--- a/source3/rpc_client/cli_lsarpc.c
+++ b/source3/rpc_client/cli_lsarpc.c
@@ -33,6 +33,185 @@ extern int DEBUGLEVEL;
/****************************************************************************
+ obtain the sid from the PDC. do some verification along the way...
+****************************************************************************/
+BOOL get_domain_sids(const char *myname,
+ DOM_SID *sid3, DOM_SID *sid5, char *servers)
+{
+ uint16 nt_pipe_fnum;
+ POLICY_HND pol;
+ fstring srv_name;
+ struct cli_state cli;
+ BOOL res = True;
+ fstring dom3;
+ fstring dom5;
+
+ if (sid3 == NULL && sid5 == NULL)
+ {
+ /* don't waste my time... */
+ return False;
+ }
+
+ if (!cli_connect_serverlist(&cli, servers))
+ {
+ DEBUG(0,("get_domain_sids: unable to initialise client connection.\n"));
+ return False;
+ }
+
+ /*
+ * Ok - we have an anonymous connection to the IPC$ share.
+ * Now start the NT Domain stuff :-).
+ */
+
+ fstrcpy(dom3, "");
+ fstrcpy(dom5, "");
+ if (sid3 != NULL)
+ {
+ ZERO_STRUCTP(sid3);
+ }
+ if (sid5 != NULL)
+ {
+ ZERO_STRUCTP(sid5);
+ }
+
+ fstrcpy(srv_name, "\\\\");
+ fstrcat(srv_name, myname);
+ strupper(srv_name);
+
+ /* open LSARPC session. */
+ res = res ? cli_nt_session_open(&cli, PIPE_LSARPC, &nt_pipe_fnum) : False;
+
+ /* lookup domain controller; receive a policy handle */
+ res = res ? lsa_open_policy(&cli, nt_pipe_fnum, srv_name, &pol, False) : False;
+
+ if (sid3 != NULL)
+ {
+ /* send client info query, level 3. receive domain name and sid */
+ res = res ? lsa_query_info_pol(&cli, nt_pipe_fnum, &pol, 3, dom3, sid3) : False;
+ }
+
+ if (sid5 != NULL)
+ {
+ /* send client info query, level 5. receive domain name and sid */
+ res = res ? lsa_query_info_pol(&cli, nt_pipe_fnum, &pol, 5, dom5, sid5) : False;
+ }
+
+ /* close policy handle */
+ res = res ? lsa_close(&cli, nt_pipe_fnum, &pol) : False;
+
+ /* close the session */
+ cli_nt_session_close(&cli, nt_pipe_fnum);
+ cli_ulogoff(&cli);
+ cli_shutdown(&cli);
+
+ if (res)
+ {
+ pstring sid;
+ DEBUG(2,("LSA Query Info Policy\n"));
+ if (sid3 != NULL)
+ {
+ sid_to_string(sid, sid3);
+ DEBUG(2,("Domain Member - Domain: %s SID: %s\n", dom3, sid));
+ }
+ if (sid5 != NULL)
+ {
+ sid_to_string(sid, sid5);
+ DEBUG(2,("Domain Controller - Domain: %s SID: %s\n", dom5, sid));
+ }
+ }
+ else
+ {
+ DEBUG(1,("lsa query info failed\n"));
+ }
+
+ return res;
+}
+
+/****************************************************************************
+ obtain a sid and domain name from a Domain Controller.
+****************************************************************************/
+BOOL get_trust_sid_and_domain(const char* myname, char *server,
+ DOM_SID *sid,
+ char *domain, size_t len)
+{
+ uint16 nt_pipe_fnum;
+ POLICY_HND pol;
+ fstring srv_name;
+ struct cli_state cli;
+ BOOL res = True;
+ BOOL res1 = True;
+ DOM_SID sid3;
+ DOM_SID sid5;
+ fstring dom3;
+ fstring dom5;
+
+ if (!cli_connect_serverlist(&cli, server))
+ {
+ DEBUG(0,("get_trust_sid: unable to initialise client connection.\n"));
+ return False;
+ }
+
+ fstrcpy(dom3, "");
+ fstrcpy(dom5, "");
+ ZERO_STRUCT(sid3);
+ ZERO_STRUCT(sid5);
+
+ fstrcpy(srv_name, "\\\\");
+ fstrcat(srv_name, myname);
+ strupper(srv_name);
+
+ /* open LSARPC session. */
+ res = res ? cli_nt_session_open(&cli, PIPE_LSARPC, &nt_pipe_fnum) : False;
+
+ /* lookup domain controller; receive a policy handle */
+ res = res ? lsa_open_policy(&cli, nt_pipe_fnum, srv_name, &pol, False) : False;
+
+ /* send client info query, level 3. receive domain name and sid */
+ res1 = res ? lsa_query_info_pol(&cli, nt_pipe_fnum, &pol, 3, dom3, &sid3) : False;
+
+ /* send client info query, level 5. receive domain name and sid */
+ res1 = res1 ? lsa_query_info_pol(&cli, nt_pipe_fnum, &pol, 5, dom5, &sid5) : False;
+
+ /* close policy handle */
+ res = res ? lsa_close(&cli, nt_pipe_fnum, &pol) : False;
+
+ /* close the session */
+ cli_nt_session_close(&cli, nt_pipe_fnum);
+ cli_ulogoff(&cli);
+ cli_shutdown(&cli);
+
+ if (res1)
+ {
+ pstring sid_str;
+ DEBUG(2,("LSA Query Info Policy\n"));
+ sid_to_string(sid_str, &sid3);
+ DEBUG(2,("Domain Member - Domain: %s SID: %s\n",
+ dom3, sid_str));
+ sid_to_string(sid_str, &sid5);
+ DEBUG(2,("Domain Controller - Domain: %s SID: %s\n",
+ dom5, sid_str));
+
+ if (dom5[0] != 0 && sid_equal(&sid3, &sid5))
+ {
+ safe_strcpy(domain, dom5, len);
+ sid_copy(sid, &sid5);
+ }
+ else
+ {
+ DEBUG(2,("Server %s is not a PDC\n", server));
+ return False;
+ }
+
+ }
+ else
+ {
+ DEBUG(1,("lsa query info failed\n"));
+ }
+
+ return res1;
+}
+
+/****************************************************************************
do a LSA Open Policy
****************************************************************************/
BOOL lsa_open_policy(struct cli_state *cli, uint16 fnum,
diff --git a/source3/rpc_client/cli_samr.c b/source3/rpc_client/cli_samr.c
index d25b6e2305..97e218b1b3 100644
--- a/source3/rpc_client/cli_samr.c
+++ b/source3/rpc_client/cli_samr.c
@@ -32,455 +32,6 @@
extern int DEBUGLEVEL;
-
-/****************************************************************************
-do a SAMR create domain user
-****************************************************************************/
-BOOL create_samr_domain_user(struct cli_state *cli, uint16 fnum,
- POLICY_HND *pol_open_domain,
- const char *acct_name, uint16 acb_info,
- uint32 *rid)
-{
- POLICY_HND pol_open_user;
- BOOL ret = True;
-
- if (pol_open_domain == NULL || acct_name == NULL) return False;
-
- /* send create user */
- if (!samr_create_dom_user(cli, fnum,
- pol_open_domain,
- acct_name, acb_info, 0xe005000b,
- &pol_open_user, rid))
- {
- return False;
- }
-
- DEBUG(5,("create_samr_domain_user: name: %s rid 0x%x\n",
- acct_name, *rid));
-
- return samr_close(cli, fnum, &pol_open_user) && ret;
-}
-
-/****************************************************************************
-do a SAMR create domain alias
-****************************************************************************/
-BOOL create_samr_domain_alias(struct cli_state *cli, uint16 fnum,
- POLICY_HND *pol_open_domain,
- const char *acct_name, const char *acct_desc,
- uint32 *rid)
-{
- POLICY_HND pol_open_alias;
- ALIAS_INFO_CTR ctr;
- BOOL ret = True;
-
- if (pol_open_domain == NULL || acct_name == NULL || acct_desc == NULL) return False;
-
- /* send create alias */
- if (!samr_create_dom_alias(cli, fnum,
- pol_open_domain,
- acct_name,
- &pol_open_alias, rid))
- {
- return False;
- }
-
- DEBUG(5,("create_samr_domain_alias: name: %s rid 0x%x\n",
- acct_name, *rid));
-
- ctr.switch_value1 = 3;
- make_samr_alias_info3(&ctr.alias.info3, acct_desc);
-
- /* send set alias info */
- if (!samr_set_aliasinfo(cli, fnum,
- &pol_open_alias,
- &ctr))
- {
- DEBUG(5,("create_samr_domain_alias: error in samr_set_aliasinfo\n"));
- ret = False;
- }
-
- return samr_close(cli, fnum,&pol_open_alias) && ret;
-}
-
-/****************************************************************************
-do a SAMR create domain group
-****************************************************************************/
-BOOL create_samr_domain_group(struct cli_state *cli, uint16 fnum,
- POLICY_HND *pol_open_domain,
- const char *acct_name, const char *acct_desc,
- uint32 *rid)
-{
- POLICY_HND pol_open_group;
- GROUP_INFO_CTR ctr;
- BOOL ret = True;
-
- if (pol_open_domain == NULL || acct_name == NULL || acct_desc == NULL) return False;
-
- /* send create group*/
- if (!samr_create_dom_group(cli, fnum,
- pol_open_domain,
- acct_name,
- &pol_open_group, rid))
- {
- return False;
- }
-
- DEBUG(5,("create_samr_domain_group: name: %s rid 0x%x\n",
- acct_name, *rid));
-
- ctr.switch_value1 = 4;
- ctr.switch_value2 = 4;
- make_samr_group_info4(&ctr.group.info4, acct_desc);
-
- /* send user groups query */
- if (!samr_set_groupinfo(cli, fnum,
- &pol_open_group,
- &ctr))
- {
- DEBUG(5,("create_samr_domain_group: error in samr_set_groupinfo\n"));
- ret = False;
- }
-
- return samr_close(cli, fnum,&pol_open_group) && ret;
-}
-
-/****************************************************************************
-do a SAMR query user groups
-****************************************************************************/
-BOOL get_samr_query_usergroups(struct cli_state *cli, uint16 fnum,
- const POLICY_HND *pol_open_domain,
- uint32 user_rid,
- uint32 *num_groups, DOM_GID **gid)
-{
- POLICY_HND pol_open_user;
- BOOL ret = True;
-
- if (pol_open_domain == NULL || num_groups == NULL || gid == NULL) return False;
-
- /* send open domain (on user sid) */
- if (!samr_open_user(cli, fnum,
- pol_open_domain,
- 0x02011b, user_rid,
- &pol_open_user))
- {
- return False;
- }
-
- /* send user groups query */
- if (!samr_query_usergroups(cli, fnum,
- &pol_open_user,
- num_groups, gid))
- {
- DEBUG(5,("samr_query_usergroups: error in query user groups\n"));
- ret = False;
- }
-
- return samr_close(cli, fnum,&pol_open_user) && ret;
-}
-
-/****************************************************************************
-do a SAMR delete group
-****************************************************************************/
-BOOL delete_samr_dom_group(struct cli_state *cli, uint16 fnum,
- POLICY_HND *pol_open_domain,
- uint32 group_rid)
-{
- POLICY_HND pol_open_group;
-
- if (pol_open_domain == NULL) return False;
-
- /* send open domain (on group rid) */
- if (!samr_open_group(cli, fnum,pol_open_domain,
- 0x00000010, group_rid,
- &pol_open_group))
- {
- return False;
- }
-
- /* send group delete */
- if (!samr_delete_dom_group(cli, fnum,&pol_open_group))
-
- {
- DEBUG(5,("delete_samr_dom_group: error in delete domain group\n"));
- samr_close(cli, fnum,&pol_open_group);
- return False;
- }
-
- return True;
-}
-
-
-/****************************************************************************
-do a SAMR query group members
-****************************************************************************/
-BOOL get_samr_query_groupmem(struct cli_state *cli, uint16 fnum,
- const POLICY_HND *pol_open_domain,
- uint32 group_rid, uint32 *num_mem,
- uint32 **rid, uint32 **attr)
-{
- POLICY_HND pol_open_group;
- BOOL ret = True;
-
- if (pol_open_domain == NULL || num_mem == NULL || rid == NULL || attr == NULL) return False;
-
- /* send open domain (on group sid) */
- if (!samr_open_group(cli, fnum, pol_open_domain,
- 0x00000010, group_rid,
- &pol_open_group))
- {
- return False;
- }
-
- /* send group info query */
- if (!samr_query_groupmem(cli, fnum,&pol_open_group, num_mem, rid, attr))
-
- {
- DEBUG(5,("samr_query_group: error in query group members\n"));
- ret = False;
- }
-
- return samr_close(cli, fnum,&pol_open_group) && ret;
-}
-
-/****************************************************************************
-do a SAMR delete alias
-****************************************************************************/
-BOOL delete_samr_dom_alias(struct cli_state *cli, uint16 fnum,
- POLICY_HND *pol_open_domain,
- uint32 alias_rid)
-{
- POLICY_HND pol_open_alias;
-
- if (pol_open_domain == NULL) return False;
-
- /* send open domain (on alias rid) */
- if (!samr_open_alias(cli, fnum,pol_open_domain,
- 0x000f001f, alias_rid, &pol_open_alias))
- {
- return False;
- }
-
- /* send alias delete */
- if (!samr_delete_dom_alias(cli, fnum,&pol_open_alias))
-
- {
- DEBUG(5,("delete_samr_dom_alias: error in delete domain alias\n"));
- samr_close(cli, fnum,&pol_open_alias);
- return False;
- }
-
- return True;
-}
-
-
-/****************************************************************************
-do a SAMR query alias members
-****************************************************************************/
-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)
-{
- POLICY_HND pol_open_alias;
- BOOL ret = True;
-
- if (pol_open_domain == NULL || num_mem == NULL || sid == NULL) return False;
-
- /* send open domain (on alias sid) */
- if (!samr_open_alias(cli, fnum, pol_open_domain,
- 0x000f001f, alias_rid,
- &pol_open_alias))
- {
- return False;
- }
-
- /* send alias info query */
- if (!samr_query_aliasmem(cli, fnum, &pol_open_alias, num_mem, sid))
-
- {
- DEBUG(5,("samr_query_alias: error in query alias members\n"));
- ret = False;
- }
-
- return samr_close(cli, fnum,&pol_open_alias) && ret;
-}
-
-/****************************************************************************
-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,
- 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_userinfo(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 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, 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,
- 0x02011b, user_rid,
- &pol_open_user))
- {
- return False;
- }
-
- /* send user info query */
- if (!samr_query_userinfo(cli, fnum,
- &pol_open_user,
- info_level, usr))
- {
- DEBUG(5,("samr_query_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 query group info
-****************************************************************************/
-BOOL get_samr_query_groupinfo(struct cli_state *cli, uint16 fnum,
- const POLICY_HND *pol_open_domain,
- uint32 info_level,
- uint32 group_rid, GROUP_INFO_CTR *ctr)
-{
- POLICY_HND pol_open_group;
- BOOL ret = True;
-
- if (pol_open_domain == NULL || ctr == NULL) return False;
-
- bzero(ctr, sizeof(*ctr));
-
- /* send open domain (on group sid) */
- if (!samr_open_group(cli, fnum,
- pol_open_domain,
- 0x02000000, group_rid, &pol_open_group))
- {
- return False;
- }
-
- /* send group info query */
- if (!samr_query_groupinfo(cli, fnum,
- &pol_open_group,
- info_level, ctr))
- {
- DEBUG(5,("samr_query_groupinfo: error in query group info, level 0x%x\n",
- info_level));
- ret = False;
- }
-
- return samr_close(cli, fnum,&pol_open_group) && ret;
-}
-
-/****************************************************************************
-do a SAMR query alias info
-****************************************************************************/
-BOOL get_samr_query_aliasinfo(struct cli_state *cli, uint16 fnum,
- const POLICY_HND *pol_open_domain,
- uint32 info_level,
- uint32 alias_rid, ALIAS_INFO_CTR *ctr)
-{
- POLICY_HND pol_open_alias;
- BOOL ret = True;
-
- if (pol_open_domain == NULL || ctr == NULL) return False;
-
- bzero(ctr, sizeof(*ctr));
-
- /* send open domain (on alias sid) */
- if (!samr_open_alias(cli, fnum,
- pol_open_domain,
- 0x02000000, alias_rid, &pol_open_alias))
- {
- return False;
- }
-
- /* send alias info query */
- if (!samr_query_aliasinfo(cli, fnum,
- &pol_open_alias,
- info_level, ctr))
- {
- DEBUG(5,("samr_query_aliasinfo: error in query alias info, level 0x%x\n",
- info_level));
- ret = False;
- }
-
- return samr_close(cli, fnum,&pol_open_alias) && ret;
-}
-
/****************************************************************************
do a SAMR change user password command
****************************************************************************/
diff --git a/source3/rpc_client/msrpc_samr.c b/source3/rpc_client/msrpc_samr.c
new file mode 100644
index 0000000000..76d6d8932c
--- /dev/null
+++ b/source3/rpc_client/msrpc_samr.c
@@ -0,0 +1,1427 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 1.9.
+ NT Domain Authentication SMB / MSRPC client
+ Copyright (C) Andrew Tridgell 1994-1999
+ Copyright (C) Luke Kenneth Casson Leighton 1996-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
+ the Free Software Foundation; either version 2 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, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+
+
+#ifdef SYSLOG
+#undef SYSLOG
+#endif
+
+#include "includes.h"
+#include "nterr.h"
+
+extern int DEBUGLEVEL;
+
+#define DEBUG_TESTING
+
+BOOL req_user_info(struct cli_state *cli, uint16 fnum,
+ POLICY_HND *pol_dom,
+ const char *domain,
+ const DOM_SID *sid,
+ uint32 user_rid,
+ USER_INFO_FN(usr_inf))
+{
+ SAM_USER_INFO_21 usr;
+ /* send user info query, level 0x15 */
+ if (get_samr_query_userinfo(cli, fnum,
+ pol_dom,
+ 0x15, user_rid, &usr))
+ {
+ if (usr_inf != NULL)
+ {
+ usr_inf(domain, sid, user_rid, &usr);
+ }
+ return True;
+ }
+ return False;
+}
+
+/****************************************************************************
+SAM Query User Groups.
+****************************************************************************/
+uint32 sam_query_usergroups(struct cli_state *cli, uint16 fnum,
+ const POLICY_HND *pol_dom,
+ const char *domain,
+ const DOM_SID *sid,
+ uint32 user_rid,
+ const char *user_name,
+ uint32 *num_groups,
+ DOM_GID **gid,
+ char ***name,
+ uint32 **type,
+ USER_MEM_FN(usr_mem))
+{
+ uint32 num_names = 0;
+ (*gid) = NULL;
+ /* send user group query */
+ if (get_samr_query_usergroups(cli, fnum,
+ pol_dom,
+ user_rid, num_groups, gid) &&
+ gid != NULL)
+ {
+ uint32 i;
+ uint32 *rid_mem;
+
+ rid_mem = (uint32*)malloc((*num_groups) * sizeof(rid_mem[0]));
+
+ if (rid_mem == NULL)
+ {
+ free(*gid);
+ (*gid) = NULL;
+ return 0;
+ }
+
+ for (i = 0; i < (*num_groups); i++)
+ {
+ rid_mem[i] = (*gid)[i].g_rid;
+ }
+
+ if (samr_query_lookup_rids(cli, fnum,
+ pol_dom, 0x3e8,
+ (*num_groups), rid_mem,
+ &num_names, name, type))
+ {
+ usr_mem(domain, sid,
+ user_rid, user_name,
+ num_names, rid_mem, *name, *type);
+ }
+ }
+
+ return num_names;
+}
+
+static uint32 req_group_info(struct cli_state *cli, uint16 fnum,
+ const POLICY_HND *pol_dom,
+ const char *domain, const DOM_SID *sid,
+ uint32 user_rid, const char *user_name,
+ USER_MEM_FN(usr_mem))
+{
+ uint32 num_groups;
+ uint32 num_names;
+ DOM_GID *gid = NULL;
+ char **name = NULL;
+ uint32 *type = NULL;
+
+ num_names = sam_query_usergroups(cli, fnum, pol_dom,
+ domain, sid,
+ user_rid, user_name,
+ &num_groups, &gid,
+ &name, &type, usr_mem);
+
+ free_char_array(num_names, name);
+ if (type != NULL)
+ {
+ free(type);
+ }
+
+ if (gid != NULL)
+ {
+ free(gid);
+ }
+
+ return num_names;
+}
+
+static void req_alias_info(struct cli_state *cli, uint16 fnum,
+ const POLICY_HND *pol_dom,
+ const char *domain,
+ const DOM_SID *sid1, uint32 user_rid,
+ const char *user_name,
+ USER_MEM_FN(usr_mem))
+{
+ uint32 num_aliases;
+ uint32 *rid_mem = NULL;
+ uint32 *ptr_sid;
+ DOM_SID2 *als_sid;
+
+ ptr_sid = (uint32*) malloc(sizeof(ptr_sid[0]) * 1);
+ als_sid = (DOM_SID2*)malloc(sizeof(als_sid[0]) * 1);
+
+ sid_copy(&als_sid[0].sid, sid1);
+ sid_append_rid(&als_sid[0].sid, user_rid);
+ als_sid[0].num_auths = als_sid[0].sid.num_auths;
+
+ ptr_sid[0] = 1;
+
+ /* send user alias query */
+ if (samr_query_useraliases(cli, fnum,
+ pol_dom,
+ ptr_sid, als_sid, &num_aliases, &rid_mem))
+ {
+ uint32 num_names;
+ char **name = NULL;
+ uint32 *type = NULL;
+
+ uint32 *rid_copy = (uint32*)malloc(num_aliases * sizeof(*rid_copy));
+
+ if (rid_copy != NULL)
+ {
+ uint32 i;
+ for (i = 0; i < num_aliases; i++)
+ {
+ rid_copy[i] = rid_mem[i];
+ }
+ if (samr_query_lookup_rids(cli, fnum,
+ pol_dom, 0x3e8,
+ num_aliases, rid_copy,
+ &num_names, &name, &type))
+ {
+ usr_mem(domain, sid1,
+ user_rid, user_name,
+ num_names, rid_mem, name, type);
+ }
+ }
+
+ free_char_array(num_names, name);
+ if (type != NULL)
+ {
+ free(type);
+ }
+ }
+
+ if (rid_mem != NULL)
+ {
+ free(rid_mem);
+ rid_mem = NULL;
+ }
+
+ if (ptr_sid != NULL)
+ {
+ free(ptr_sid);
+ ptr_sid = NULL;
+ }
+ if (als_sid != NULL)
+ {
+ free(als_sid);
+ als_sid = NULL;
+ }
+}
+
+/****************************************************************************
+experimental SAM users enum.
+****************************************************************************/
+int msrpc_sam_enum_users(struct cli_state *cli,
+ const char* domain,
+ const DOM_SID *sid1,
+ const char* srv_name,
+ struct acct_info **sam,
+ uint32 *num_sam_entries,
+ USER_FN(usr_fn),
+ USER_INFO_FN(usr_inf_fn),
+ USER_MEM_FN(usr_grp_fn),
+ USER_MEM_FN(usr_als_fn))
+{
+ uint16 fnum;
+ DOM_SID sid_1_5_20;
+ uint32 user_idx;
+ BOOL res = True;
+ BOOL res1 = True;
+ BOOL res2 = True;
+ uint32 start_idx = 0x0;
+ uint16 unk_0 = 0x0;
+ uint16 acb_mask = 0;
+ uint16 unk_1 = 0x0;
+ uint32 ace_perms = 0x304; /* access control permissions */
+ uint32 status;
+ POLICY_HND sam_pol;
+ POLICY_HND pol_dom;
+ POLICY_HND pol_blt;
+
+ (*sam) = NULL;
+ (*num_sam_entries) = 0;
+
+ string_to_sid(&sid_1_5_20, "S-1-5-32");
+
+ DEBUG(5,("Number of entries:%d unk_0:%04x acb_mask:%04x unk_1:%04x\n",
+ start_idx, unk_0, acb_mask, unk_1));
+
+ /* open SAMR session. negotiate credentials */
+ res = res ? cli_nt_session_open(cli, PIPE_SAMR, &fnum) : False;
+
+ /* establish a connection. */
+ res = res ? samr_connect(cli, fnum,
+ srv_name, 0x02000000,
+ &sam_pol) : False;
+
+ /* connect to the domain */
+ res1 = res ? samr_open_domain(cli, fnum,
+ &sam_pol, ace_perms, sid1,
+ &pol_dom) : False;
+
+ /* connect to the S-1-5-20 domain */
+ res2 = res ? samr_open_domain(cli, fnum,
+ &sam_pol, ace_perms, &sid_1_5_20,
+ &pol_blt) : False;
+
+ if (res1)
+ {
+ /* read some users */
+ do
+ {
+ status = samr_enum_dom_users(cli, fnum,
+ &pol_dom,
+ &start_idx, acb_mask, unk_1, 0x100000,
+ sam, num_sam_entries);
+
+ } while (status == STATUS_MORE_ENTRIES);
+
+#if 0
+ if ((*num_sam_entries) == 0)
+ {
+ report(out_hnd, "No users\n");
+ }
+#endif
+
+ /* query all the users */
+ for (user_idx = 0; res && user_idx <
+ (*num_sam_entries); user_idx++)
+ {
+ uint32 user_rid = (*sam)[user_idx].rid;
+ char *user_name = (*sam)[user_idx].acct_name;
+
+ if (usr_fn != NULL)
+ {
+ usr_fn(domain, sid1, user_rid, user_name);
+ }
+
+ if (usr_inf_fn != NULL)
+ {
+ req_user_info(cli, fnum, &pol_dom,
+ domain, sid1,
+ user_rid,
+ usr_inf_fn);
+ }
+
+ if (usr_grp_fn != NULL)
+ {
+ req_group_info(cli, fnum, &pol_dom,
+ domain, sid1,
+ user_rid, user_name,
+ usr_grp_fn);
+ }
+
+ if (usr_als_fn != NULL)
+ {
+ req_alias_info(cli, fnum, &pol_dom,
+ domain, sid1,
+ user_rid, user_name,
+ usr_als_fn);
+ req_alias_info(cli, fnum, &pol_blt,
+ domain, sid1,
+ user_rid, user_name,
+ usr_als_fn);
+ }
+ }
+ }
+
+ res2 = res2 ? samr_close(cli, fnum, &pol_blt) : False;
+ res1 = res1 ? samr_close(cli, fnum, &pol_dom) : False;
+ res = res ? samr_close(cli, fnum, &sam_pol) : False;
+
+ /* close the session */
+ cli_nt_session_close(cli, fnum);
+
+ if (res)
+ {
+ DEBUG(5,("msrpc_sam_enum_users: succeeded\n"));
+ }
+ else
+ {
+ DEBUG(5,("msrpc_sam_enum_users: failed\n"));
+ }
+
+ return (*num_sam_entries);
+}
+
+
+/****************************************************************************
+experimental SAM domain info query.
+****************************************************************************/
+BOOL sam_query_dominfo(struct cli_state *cli,
+ const DOM_SID *sid1,
+ uint32 switch_value, SAM_UNK_CTR *ctr)
+{
+ uint16 fnum;
+ fstring srv_name;
+ BOOL res = True;
+ BOOL res1 = True;
+ BOOL res2 = True;
+ uint32 ace_perms = 0x02000000; /* absolutely no idea. */
+ POLICY_HND sam_pol;
+ POLICY_HND pol_dom;
+
+ fstrcpy(srv_name, "\\\\");
+ fstrcat(srv_name, cli->desthost);
+ strupper(srv_name);
+
+ /* open SAMR session. negotiate credentials */
+ res = res ? cli_nt_session_open(cli, PIPE_SAMR, &fnum) : False;
+
+ /* establish a connection. */
+ res = res ? samr_connect(cli, fnum,
+ srv_name, 0x02000000,
+ &sam_pol) : False;
+
+ /* connect to the domain */
+ res1 = res ? samr_open_domain(cli, fnum,
+ &sam_pol, ace_perms, sid1,
+ &pol_dom) : False;
+
+ /* send a samr 0x8 command */
+ res2 = res ? samr_query_dom_info(cli, fnum,
+ &pol_dom, switch_value, ctr) : False;
+
+ res1 = res1 ? samr_close(cli, fnum,
+ &sam_pol) : False;
+
+ res = res ? samr_close(cli, fnum,
+ &pol_dom) : False;
+
+ /* close the session */
+ cli_nt_session_close(cli, fnum);
+
+ if (res2)
+ {
+ DEBUG(5,("sam_query_dominfo: succeeded\n"));
+ }
+ else
+ {
+ DEBUG(5,("sam_query_dominfo: failed\n"));
+ }
+
+ return res2;
+}
+
+
+BOOL query_aliasinfo(struct cli_state *cli, uint16 fnum,
+ const POLICY_HND *pol_dom,
+ const char *domain,
+ const DOM_SID *sid,
+ uint32 alias_rid,
+ ALIAS_INFO_FN(grp_inf))
+{
+ ALIAS_INFO_CTR ctr;
+
+ /* send alias info query */
+ if (get_samr_query_aliasinfo(cli, fnum,
+ pol_dom,
+ 3, /* info level */
+ alias_rid, &ctr))
+ {
+ if (grp_inf != NULL)
+ {
+ grp_inf(domain, sid, alias_rid, &ctr);
+ }
+ return True;
+ }
+ return False;
+}
+
+BOOL sam_query_aliasmem(struct cli_state *cli, uint16 fnum,
+ const POLICY_HND *pol_dom,
+ uint32 alias_rid,
+ uint32 *num_names,
+ DOM_SID ***sids,
+ char ***name,
+ uint8 **type)
+{
+ BOOL res3 = True;
+ BOOL res4 = True;
+ DOM_SID2 sid_mem[MAX_LOOKUP_SIDS];
+ uint32 num_aliases = 0;
+
+ *sids = NULL;
+ *num_names = 0;
+ *name = NULL;
+ *type = NULL;
+
+ /* get alias members */
+ res3 = get_samr_query_aliasmem(cli, fnum,
+ pol_dom,
+ alias_rid, &num_aliases, sid_mem);
+
+ if (res3 && num_aliases != 0)
+ {
+ fstring srv_name;
+ uint16 fnum_lsa;
+ POLICY_HND lsa_pol;
+
+ uint32 i;
+ uint32 numsids = 0;
+
+ fstrcpy(srv_name, "\\\\");
+ fstrcat(srv_name, cli->desthost);
+ strupper(srv_name);
+
+ for (i = 0; i < num_aliases; i++)
+ {
+ add_sid_to_array(&numsids, sids, &sid_mem[i].sid);
+ }
+
+ /* open LSARPC session. */
+ res3 = res3 ? cli_nt_session_open(cli, PIPE_LSARPC, &fnum_lsa) : False;
+
+ /* lookup domain controller; receive a policy handle */
+ res3 = res3 ? lsa_open_policy(cli, fnum_lsa,
+ srv_name,
+ &lsa_pol, True) : False;
+
+ /* send lsa lookup sids call */
+ res4 = res3 ? lsa_lookup_sids(cli, fnum_lsa,
+ &lsa_pol,
+ num_aliases, *sids,
+ name, type, num_names) : False;
+
+ res3 = res3 ? lsa_close(cli, fnum_lsa, &lsa_pol) : False;
+
+ cli_nt_session_close(cli, fnum_lsa);
+ }
+
+ if (!res4)
+ {
+ free_char_array(*num_names, *name);
+ if ((*type) != NULL)
+ {
+ free(*type);
+ }
+ if ((*sids) != NULL)
+ {
+ free_sid_array(num_aliases, *sids);
+ }
+ *num_names = 0;
+ *name = NULL;
+ *type = NULL;
+ *sids = NULL;
+ }
+
+ return res4;
+}
+
+BOOL req_aliasmem_info(struct cli_state *cli, uint16 fnum,
+ const POLICY_HND *pol_dom,
+ const char *domain,
+ const DOM_SID *sid,
+ uint32 alias_rid,
+ const char *alias_name,
+ ALIAS_MEM_FN(als_mem))
+{
+ uint32 num_names = 0;
+ char **name = NULL;
+ uint8 *type = NULL;
+ DOM_SID **sids = NULL;
+
+ if (sam_query_aliasmem(cli, fnum, pol_dom, alias_rid,
+ &num_names, &sids,
+ &name, &type))
+ {
+ als_mem(domain, sid,
+ alias_rid, alias_name,
+ num_names, sids, name, type);
+
+ free_char_array(num_names, name);
+ if (type != NULL)
+ {
+ free(type);
+ }
+ if (sids != NULL)
+ {
+ free_sid_array(num_names, sids);
+ }
+ return True;
+ }
+ return False;
+}
+
+BOOL sam_query_groupmem(struct cli_state *cli, uint16 fnum,
+ const POLICY_HND *pol_dom,
+ uint32 group_rid,
+ uint32 *num_names,
+ uint32 **rid_mem,
+ char ***name,
+ uint32 **type)
+{
+ uint32 num_mem;
+ uint32 *attr_mem = NULL;
+ BOOL res3;
+
+ *rid_mem = NULL;
+ *num_names = 0;
+ *name = NULL;
+ *type = NULL;
+
+ /* get group members */
+ res3 = get_samr_query_groupmem(cli, fnum,
+ pol_dom,
+ group_rid, &num_mem, rid_mem, &attr_mem);
+
+ if (res3 && num_mem != 0)
+ {
+ uint32 *rid_copy = (uint32*)malloc(num_mem *
+ sizeof(rid_copy[0]));
+
+ if (rid_copy != NULL)
+ {
+ uint32 i;
+ for (i = 0; i < num_mem; i++)
+ {
+ rid_copy[i] = (*rid_mem)[i];
+ }
+ /* resolve names */
+ res3 = samr_query_lookup_rids(cli, fnum,
+ pol_dom, 1000,
+ num_mem, rid_copy, num_names, name, type);
+ }
+ }
+ else
+ {
+ if (attr_mem != NULL)
+ {
+ free(attr_mem);
+ }
+ if ((*rid_mem) != NULL)
+ {
+ free(*rid_mem);
+ }
+ attr_mem = NULL;
+ *rid_mem = NULL;
+ }
+
+ if (!res3)
+ {
+ free_char_array(*num_names, *name);
+ if ((*type) != NULL)
+ {
+ free(*type);
+ }
+ *num_names = 0;
+ *name = NULL;
+ *type = NULL;
+ }
+
+ if (attr_mem != NULL)
+ {
+ free(attr_mem);
+ }
+
+ return res3;
+}
+
+BOOL query_groupinfo(struct cli_state *cli, uint16 fnum,
+ const POLICY_HND *pol_dom,
+ const char *domain,
+ const DOM_SID *sid,
+ uint32 group_rid,
+ GROUP_INFO_FN(grp_inf))
+{
+ GROUP_INFO_CTR ctr;
+
+ /* send group info query */
+ if (get_samr_query_groupinfo(cli, fnum,
+ pol_dom,
+ 1, /* info level */
+ group_rid, &ctr))
+ {
+ if (grp_inf != NULL)
+ {
+ grp_inf(domain, sid, group_rid, &ctr);
+ }
+ return True;
+ }
+ return False;
+}
+
+BOOL req_groupmem_info(struct cli_state *cli, uint16 fnum,
+ const POLICY_HND *pol_dom,
+ const char *domain,
+ const DOM_SID *sid,
+ uint32 group_rid,
+ const char *group_name,
+ GROUP_MEM_FN(grp_mem))
+{
+ uint32 num_names = 0;
+ char **name = NULL;
+ uint32 *type = NULL;
+ uint32 *rid_mem = NULL;
+
+ if (sam_query_groupmem(cli, fnum, pol_dom, group_rid,
+ &num_names, &rid_mem, &name, &type))
+ {
+ grp_mem(domain, sid,
+ group_rid, group_name,
+ num_names, rid_mem, name, type);
+
+ free_char_array(num_names, name);
+ if (type != NULL)
+ {
+ free(type);
+ }
+ if (rid_mem != NULL)
+ {
+ free(rid_mem);
+ }
+ return True;
+ }
+ return False;
+}
+
+/****************************************************************************
+SAM Domains query.
+ DOMAIN_INFO_FN(dom_inf_fn),
+ DOMAIN_MEM_FN(dom_mem_fn))
+****************************************************************************/
+uint32 msrpc_sam_enum_domains(struct cli_state *cli,
+ const char* srv_name,
+ struct acct_info **sam,
+ uint32 *num_sam_entries,
+ DOMAIN_FN(dom_fn))
+{
+ uint16 fnum;
+ BOOL res = True;
+ uint32 ace_perms = 0x02000000; /* access control permissions. */
+ POLICY_HND sam_pol;
+ uint32 status;
+
+ /* open SAMR session. negotiate credentials */
+ res = res ? cli_nt_session_open(cli, PIPE_SAMR, &fnum) : False;
+
+ /* establish a connection. */
+ res = res ? samr_connect(cli, fnum,
+ srv_name, ace_perms,
+ &sam_pol) : False;
+
+ (*sam) = NULL;
+ (*num_sam_entries) = 0;
+
+ if (res)
+ {
+ uint32 domain_idx;
+ uint32 start_idx = 0;
+ /* read some domains */
+ do
+ {
+ status = samr_enum_domains(cli, fnum,
+ &sam_pol,
+ &start_idx, 0x10000,
+ sam, num_sam_entries);
+
+ } while (status == STATUS_MORE_ENTRIES);
+
+#if 0
+ if ((*num_sam_entries) == 0)
+ {
+ report(out_hnd, "No domains\n");
+ }
+#endif
+
+ for (domain_idx = 0; domain_idx < (*num_sam_entries); domain_idx++)
+ {
+ char *domain_name = (*sam)[domain_idx].acct_name;
+
+ if (dom_fn != NULL)
+ {
+ dom_fn(domain_name);
+ }
+
+#if 0
+ if (dom_inf_fn != NULL)
+ {
+ query_domaininfo(cli, fnum, &sam_pol,
+ domain_name,
+ dom_inf_fn);
+ }
+ if (dom_mem_fn != NULL)
+ {
+ req_domainmem_info(cli, fnum, &sam_pol,
+ domain_name,
+ dom_mem_fn);
+ }
+#endif
+ }
+ }
+
+ res = res ? samr_close(cli, fnum, &sam_pol) : False;
+
+ /* close the session */
+ cli_nt_session_close(cli, fnum);
+
+ if (res)
+ {
+ DEBUG(5,("msrpc_sam_enum_domains: succeeded\n"));
+ }
+ else
+ {
+ DEBUG(5,("msrpc_sam_enum_domains: failed\n"));
+ }
+ return (*num_sam_entries);
+}
+
+/****************************************************************************
+SAM groups query.
+****************************************************************************/
+uint32 msrpc_sam_enum_groups(struct cli_state *cli,
+ const char* domain,
+ const DOM_SID *sid1,
+ const char* srv_name,
+ struct acct_info **sam,
+ uint32 *num_sam_entries,
+ GROUP_FN(grp_fn),
+ GROUP_INFO_FN(grp_inf_fn),
+ GROUP_MEM_FN(grp_mem_fn))
+{
+ uint16 fnum;
+ BOOL res = True;
+ uint32 ace_perms = 0x02000000; /* access control permissions. */
+ POLICY_HND sam_pol;
+ POLICY_HND pol_dom;
+ uint32 status;
+
+ /* open SAMR session. negotiate credentials */
+ res = res ? cli_nt_session_open(cli, PIPE_SAMR, &fnum) : False;
+
+ /* establish a connection. */
+ res = res ? samr_connect(cli, fnum,
+ srv_name, 0x02000000,
+ &sam_pol) : False;
+
+ /* connect to the domain */
+ res = res ? samr_open_domain(cli, fnum,
+ &sam_pol, ace_perms, sid1,
+ &pol_dom) : False;
+
+ (*sam) = NULL;
+ (*num_sam_entries) = 0;
+
+ if (res)
+ {
+ uint32 group_idx;
+ uint32 start_idx = 0;
+ /* read some groups */
+ do
+ {
+ status = samr_enum_dom_groups(cli, fnum,
+ &pol_dom,
+ &start_idx, 0x100000,
+ sam, num_sam_entries);
+
+ } while (status == STATUS_MORE_ENTRIES);
+
+#if 0
+ if ((*num_sam_entries) == 0)
+ {
+ report(out_hnd, "No groups\n");
+ }
+#endif
+
+ for (group_idx = 0; group_idx < (*num_sam_entries); group_idx++)
+ {
+ uint32 group_rid = (*sam)[group_idx].rid;
+ char *group_name = (*sam)[group_idx].acct_name;
+
+ if (grp_fn != NULL)
+ {
+ grp_fn(domain, sid1, group_rid, group_name);
+ }
+
+ if (grp_inf_fn != NULL)
+ {
+ query_groupinfo(cli, fnum, &pol_dom,
+ domain, sid1,
+ group_rid,
+ grp_inf_fn);
+ }
+ if (grp_mem_fn != NULL)
+ {
+ req_groupmem_info(cli, fnum, &pol_dom,
+ domain, sid1,
+ group_rid, group_name,
+ grp_mem_fn);
+ }
+ }
+ }
+
+ res = res ? samr_close(cli, fnum, &pol_dom) : False;
+ res = res ? samr_close(cli, fnum, &sam_pol) : False;
+
+ /* close the session */
+ cli_nt_session_close(cli, fnum);
+
+ if (res)
+ {
+ DEBUG(5,("msrpc_sam_enum_groups: succeeded\n"));
+ }
+ else
+ {
+ DEBUG(5,("msrpc_sam_enum_groups: failed\n"));
+ }
+ return (*num_sam_entries);
+}
+
+/****************************************************************************
+SAM aliases query.
+****************************************************************************/
+uint32 msrpc_sam_enum_aliases(struct cli_state *cli,
+ const char* domain,
+ const DOM_SID *sid1,
+ const char* srv_name,
+ struct acct_info **sam,
+ uint32 *num_sam_entries,
+ ALIAS_FN(als_fn),
+ ALIAS_INFO_FN(als_inf_fn),
+ ALIAS_MEM_FN(als_mem_fn))
+{
+ uint16 fnum;
+ BOOL res = True;
+ uint32 ace_perms = 0x02000000; /* access control permissions */
+ POLICY_HND sam_pol;
+ POLICY_HND pol_dom;
+ uint32 status = 0x0;
+
+ /* open SAMR session. negotiate credentials */
+ res = res ? cli_nt_session_open(cli, PIPE_SAMR, &fnum) : False;
+
+ /* establish a connection. */
+ res = res ? samr_connect(cli, fnum,
+ srv_name, 0x02000000,
+ &sam_pol) : False;
+
+ /* connect to the domain */
+ res = res ? samr_open_domain(cli, fnum,
+ &sam_pol, ace_perms, sid1,
+ &pol_dom) : False;
+
+ (*sam) = NULL;
+ (*num_sam_entries) = 0;
+
+ if (res)
+ {
+ uint32 alias_idx;
+ uint32 start_idx = 0;
+ /* read some groups */
+ do
+ {
+ status = samr_enum_dom_aliases(cli, fnum,
+ &pol_dom,
+ &start_idx, 0x100000,
+ sam, num_sam_entries);
+
+ } while (status == STATUS_MORE_ENTRIES);
+
+#if 0
+ if ((*num_sam_entries) == 0)
+ {
+ report(out_hnd, "No aliases\n");
+ }
+#endif
+
+ for (alias_idx = 0; alias_idx < (*num_sam_entries); alias_idx++)
+ {
+ uint32 alias_rid = (*sam)[alias_idx].rid;
+ char *alias_name = (*sam)[alias_idx].acct_name;
+
+ if (als_fn != NULL)
+ {
+ als_fn(domain, sid1, alias_rid, alias_name);
+ }
+
+ if (als_inf_fn != NULL)
+ {
+ query_aliasinfo(cli, fnum, &pol_dom,
+ domain, sid1,
+ alias_rid,
+ als_inf_fn);
+ }
+ if (als_mem_fn != NULL)
+ {
+ req_aliasmem_info(cli, fnum, &pol_dom,
+ domain, sid1,
+ alias_rid, alias_name,
+ als_mem_fn);
+ }
+ }
+ }
+
+ res = res ? samr_close(cli, fnum, &sam_pol) : False;
+ res = res ? samr_close(cli, fnum, &pol_dom) : False;
+
+ /* close the session */
+ cli_nt_session_close(cli, fnum);
+
+ if (res)
+ {
+ DEBUG(5,("msrpc_sam_enum_aliases: succeeded\n"));
+ }
+ else
+ {
+ DEBUG(5,("msrpc_sam_enum_aliases: failed\n"));
+ }
+
+ return (*num_sam_entries);
+}
+
+/****************************************************************************
+do a SAMR create domain user
+****************************************************************************/
+BOOL create_samr_domain_user(struct cli_state *cli, uint16 fnum,
+ POLICY_HND *pol_open_domain,
+ const char *acct_name, uint16 acb_info,
+ uint32 *rid)
+{
+ POLICY_HND pol_open_user;
+ BOOL ret = True;
+
+ if (pol_open_domain == NULL || acct_name == NULL) return False;
+
+ /* send create user */
+ if (!samr_create_dom_user(cli, fnum,
+ pol_open_domain,
+ acct_name, acb_info, 0xe005000b,
+ &pol_open_user, rid))
+ {
+ return False;
+ }
+
+ DEBUG(5,("create_samr_domain_user: name: %s rid 0x%x\n",
+ acct_name, *rid));
+
+ return samr_close(cli, fnum, &pol_open_user) && ret;
+}
+
+/****************************************************************************
+do a SAMR create domain alias
+****************************************************************************/
+BOOL create_samr_domain_alias(struct cli_state *cli, uint16 fnum,
+ POLICY_HND *pol_open_domain,
+ const char *acct_name, const char *acct_desc,
+ uint32 *rid)
+{
+ POLICY_HND pol_open_alias;
+ ALIAS_INFO_CTR ctr;
+ BOOL ret = True;
+
+ if (pol_open_domain == NULL || acct_name == NULL || acct_desc == NULL) return False;
+
+ /* send create alias */
+ if (!samr_create_dom_alias(cli, fnum,
+ pol_open_domain,
+ acct_name,
+ &pol_open_alias, rid))
+ {
+ return False;
+ }
+
+ DEBUG(5,("create_samr_domain_alias: name: %s rid 0x%x\n",
+ acct_name, *rid));
+
+ ctr.switch_value1 = 3;
+ make_samr_alias_info3(&ctr.alias.info3, acct_desc);
+
+ /* send set alias info */
+ if (!samr_set_aliasinfo(cli, fnum,
+ &pol_open_alias,
+ &ctr))
+ {
+ DEBUG(5,("create_samr_domain_alias: error in samr_set_aliasinfo\n"));
+ ret = False;
+ }
+
+ return samr_close(cli, fnum,&pol_open_alias) && ret;
+}
+
+/****************************************************************************
+do a SAMR create domain group
+****************************************************************************/
+BOOL create_samr_domain_group(struct cli_state *cli, uint16 fnum,
+ POLICY_HND *pol_open_domain,
+ const char *acct_name, const char *acct_desc,
+ uint32 *rid)
+{
+ POLICY_HND pol_open_group;
+ GROUP_INFO_CTR ctr;
+ BOOL ret = True;
+
+ if (pol_open_domain == NULL || acct_name == NULL || acct_desc == NULL) return False;
+
+ /* send create group*/
+ if (!samr_create_dom_group(cli, fnum,
+ pol_open_domain,
+ acct_name,
+ &pol_open_group, rid))
+ {
+ return False;
+ }
+
+ DEBUG(5,("create_samr_domain_group: name: %s rid 0x%x\n",
+ acct_name, *rid));
+
+ ctr.switch_value1 = 4;
+ ctr.switch_value2 = 4;
+ make_samr_group_info4(&ctr.group.info4, acct_desc);
+
+ /* send user groups query */
+ if (!samr_set_groupinfo(cli, fnum,
+ &pol_open_group,
+ &ctr))
+ {
+ DEBUG(5,("create_samr_domain_group: error in samr_set_groupinfo\n"));
+ ret = False;
+ }
+
+ return samr_close(cli, fnum,&pol_open_group) && ret;
+}
+
+/****************************************************************************
+do a SAMR query user groups
+****************************************************************************/
+BOOL get_samr_query_usergroups(struct cli_state *cli, uint16 fnum,
+ const POLICY_HND *pol_open_domain,
+ uint32 user_rid,
+ uint32 *num_groups, DOM_GID **gid)
+{
+ POLICY_HND pol_open_user;
+ BOOL ret = True;
+
+ if (pol_open_domain == NULL || num_groups == NULL || gid == NULL) return False;
+
+ /* send open domain (on user sid) */
+ if (!samr_open_user(cli, fnum,
+ pol_open_domain,
+ 0x02011b, user_rid,
+ &pol_open_user))
+ {
+ return False;
+ }
+
+ /* send user groups query */
+ if (!samr_query_usergroups(cli, fnum,
+ &pol_open_user,
+ num_groups, gid))
+ {
+ DEBUG(5,("samr_query_usergroups: error in query user groups\n"));
+ ret = False;
+ }
+
+ return samr_close(cli, fnum,&pol_open_user) && ret;
+}
+
+/****************************************************************************
+do a SAMR delete group
+****************************************************************************/
+BOOL delete_samr_dom_group(struct cli_state *cli, uint16 fnum,
+ POLICY_HND *pol_open_domain,
+ uint32 group_rid)
+{
+ POLICY_HND pol_open_group;
+
+ if (pol_open_domain == NULL) return False;
+
+ /* send open domain (on group rid) */
+ if (!samr_open_group(cli, fnum,pol_open_domain,
+ 0x00000010, group_rid,
+ &pol_open_group))
+ {
+ return False;
+ }
+
+ /* send group delete */
+ if (!samr_delete_dom_group(cli, fnum,&pol_open_group))
+
+ {
+ DEBUG(5,("delete_samr_dom_group: error in delete domain group\n"));
+ samr_close(cli, fnum,&pol_open_group);
+ return False;
+ }
+
+ return True;
+}
+
+
+/****************************************************************************
+do a SAMR query group members
+****************************************************************************/
+BOOL get_samr_query_groupmem(struct cli_state *cli, uint16 fnum,
+ const POLICY_HND *pol_open_domain,
+ uint32 group_rid, uint32 *num_mem,
+ uint32 **rid, uint32 **attr)
+{
+ POLICY_HND pol_open_group;
+ BOOL ret = True;
+
+ if (pol_open_domain == NULL || num_mem == NULL || rid == NULL || attr == NULL) return False;
+
+ /* send open domain (on group sid) */
+ if (!samr_open_group(cli, fnum, pol_open_domain,
+ 0x00000010, group_rid,
+ &pol_open_group))
+ {
+ return False;
+ }
+
+ /* send group info query */
+ if (!samr_query_groupmem(cli, fnum,&pol_open_group, num_mem, rid, attr))
+
+ {
+ DEBUG(5,("samr_query_group: error in query group members\n"));
+ ret = False;
+ }
+
+ return samr_close(cli, fnum,&pol_open_group) && ret;
+}
+
+/****************************************************************************
+do a SAMR delete alias
+****************************************************************************/
+BOOL delete_samr_dom_alias(struct cli_state *cli, uint16 fnum,
+ POLICY_HND *pol_open_domain,
+ uint32 alias_rid)
+{
+ POLICY_HND pol_open_alias;
+
+ if (pol_open_domain == NULL) return False;
+
+ /* send open domain (on alias rid) */
+ if (!samr_open_alias(cli, fnum,pol_open_domain,
+ 0x000f001f, alias_rid, &pol_open_alias))
+ {
+ return False;
+ }
+
+ /* send alias delete */
+ if (!samr_delete_dom_alias(cli, fnum,&pol_open_alias))
+
+ {
+ DEBUG(5,("delete_samr_dom_alias: error in delete domain alias\n"));
+ samr_close(cli, fnum,&pol_open_alias);
+ return False;
+ }
+
+ return True;
+}
+
+
+/****************************************************************************
+do a SAMR query alias members
+****************************************************************************/
+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)
+{
+ POLICY_HND pol_open_alias;
+ BOOL ret = True;
+
+ if (pol_open_domain == NULL || num_mem == NULL || sid == NULL) return False;
+
+ /* send open domain (on alias sid) */
+ if (!samr_open_alias(cli, fnum, pol_open_domain,
+ 0x000f001f, alias_rid,
+ &pol_open_alias))
+ {
+ return False;
+ }
+
+ /* send alias info query */
+ if (!samr_query_aliasmem(cli, fnum, &pol_open_alias, num_mem, sid))
+
+ {
+ DEBUG(5,("samr_query_alias: error in query alias members\n"));
+ ret = False;
+ }
+
+ return samr_close(cli, fnum,&pol_open_alias) && ret;
+}
+
+/****************************************************************************
+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,
+ 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_userinfo(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 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, 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,
+ 0x02011b, user_rid,
+ &pol_open_user))
+ {
+ return False;
+ }
+
+ /* send user info query */
+ if (!samr_query_userinfo(cli, fnum,
+ &pol_open_user,
+ info_level, usr))
+ {
+ DEBUG(5,("samr_query_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 query group info
+****************************************************************************/
+BOOL get_samr_query_groupinfo(struct cli_state *cli, uint16 fnum,
+ const POLICY_HND *pol_open_domain,
+ uint32 info_level,
+ uint32 group_rid, GROUP_INFO_CTR *ctr)
+{
+ POLICY_HND pol_open_group;
+ BOOL ret = True;
+
+ if (pol_open_domain == NULL || ctr == NULL) return False;
+
+ bzero(ctr, sizeof(*ctr));
+
+ /* send open domain (on group sid) */
+ if (!samr_open_group(cli, fnum,
+ pol_open_domain,
+ 0x02000000, group_rid, &pol_open_group))
+ {
+ return False;
+ }
+
+ /* send group info query */
+ if (!samr_query_groupinfo(cli, fnum,
+ &pol_open_group,
+ info_level, ctr))
+ {
+ DEBUG(5,("samr_query_groupinfo: error in query group info, level 0x%x\n",
+ info_level));
+ ret = False;
+ }
+
+ return samr_close(cli, fnum,&pol_open_group) && ret;
+}
+
+/****************************************************************************
+do a SAMR query alias info
+****************************************************************************/
+BOOL get_samr_query_aliasinfo(struct cli_state *cli, uint16 fnum,
+ const POLICY_HND *pol_open_domain,
+ uint32 info_level,
+ uint32 alias_rid, ALIAS_INFO_CTR *ctr)
+{
+ POLICY_HND pol_open_alias;
+ BOOL ret = True;
+
+ if (pol_open_domain == NULL || ctr == NULL) return False;
+
+ bzero(ctr, sizeof(*ctr));
+
+ /* send open domain (on alias sid) */
+ if (!samr_open_alias(cli, fnum,
+ pol_open_domain,
+ 0x02000000, alias_rid, &pol_open_alias))
+ {
+ return False;
+ }
+
+ /* send alias info query */
+ if (!samr_query_aliasinfo(cli, fnum,
+ &pol_open_alias,
+ info_level, ctr))
+ {
+ DEBUG(5,("samr_query_aliasinfo: error in query alias info, level 0x%x\n",
+ info_level));
+ ret = False;
+ }
+
+ return samr_close(cli, fnum,&pol_open_alias) && ret;
+}
+
diff --git a/source3/rpcclient/cmd_samr.c b/source3/rpcclient/cmd_samr.c
index a97288d0a2..543e232065 100644
--- a/source3/rpcclient/cmd_samr.c
+++ b/source3/rpcclient/cmd_samr.c
@@ -114,940 +114,6 @@ static void sam_display_user(const char *domain, const DOM_SID *sid,
user_rid, user_name);
}
-static BOOL req_user_info(struct cli_state *cli, uint16 fnum,
- POLICY_HND *pol_dom,
- const char *domain,
- const DOM_SID *sid,
- uint32 user_rid,
- USER_INFO_FN(usr_inf))
-{
- SAM_USER_INFO_21 usr;
- /* send user info query, level 0x15 */
- if (get_samr_query_userinfo(smb_cli, fnum,
- pol_dom,
- 0x15, user_rid, &usr))
- {
- if (usr_inf != NULL)
- {
- usr_inf(domain, sid, user_rid, &usr);
- }
- return True;
- }
- return False;
-}
-
-/****************************************************************************
-SAM Query User Groups.
-****************************************************************************/
-uint32 sam_query_usergroups(struct cli_state *cli, uint16 fnum,
- const POLICY_HND *pol_dom,
- const char *domain,
- const DOM_SID *sid,
- uint32 user_rid,
- const char *user_name,
- uint32 *num_groups,
- DOM_GID **gid,
- char ***name,
- uint32 **type,
- USER_MEM_FN(usr_mem))
-{
- uint32 num_names = 0;
- (*gid) = NULL;
- /* send user group query */
- if (get_samr_query_usergroups(smb_cli, fnum,
- pol_dom,
- user_rid, num_groups, gid) &&
- gid != NULL)
- {
- uint32 i;
- uint32 *rid_mem;
-
- rid_mem = (uint32*)malloc((*num_groups) * sizeof(rid_mem[0]));
-
- if (rid_mem == NULL)
- {
- free(*gid);
- (*gid) = NULL;
- return 0;
- }
-
- for (i = 0; i < (*num_groups); i++)
- {
- rid_mem[i] = (*gid)[i].g_rid;
- }
-
- if (samr_query_lookup_rids(smb_cli, fnum,
- pol_dom, 0x3e8,
- (*num_groups), rid_mem,
- &num_names, name, type))
- {
- usr_mem(domain, sid,
- user_rid, user_name,
- num_names, rid_mem, *name, *type);
- }
- }
-
- return num_names;
-}
-
-static uint32 req_group_info(struct cli_state *cli, uint16 fnum,
- const POLICY_HND *pol_dom,
- const char *domain, const DOM_SID *sid,
- uint32 user_rid, const char *user_name,
- USER_MEM_FN(usr_mem))
-{
- uint32 num_groups;
- uint32 num_names;
- DOM_GID *gid = NULL;
- char **name = NULL;
- uint32 *type = NULL;
-
- num_names = sam_query_usergroups(cli, fnum, pol_dom,
- domain, sid,
- user_rid, user_name,
- &num_groups, &gid,
- &name, &type, usr_mem);
-
- free_char_array(num_names, name);
- if (type != NULL)
- {
- free(type);
- }
-
- if (gid != NULL)
- {
- free(gid);
- }
-
- return num_names;
-}
-
-static void req_alias_info(struct cli_state *cli, uint16 fnum,
- const POLICY_HND *pol_dom,
- const char *domain,
- const DOM_SID *sid1, uint32 user_rid,
- const char *user_name,
- USER_MEM_FN(usr_mem))
-{
- uint32 num_aliases;
- uint32 *rid_mem = NULL;
- uint32 *ptr_sid;
- DOM_SID2 *als_sid;
-
- ptr_sid = (uint32*) malloc(sizeof(ptr_sid[0]) * 1);
- als_sid = (DOM_SID2*)malloc(sizeof(als_sid[0]) * 1);
-
- sid_copy(&als_sid[0].sid, sid1);
- sid_append_rid(&als_sid[0].sid, user_rid);
- als_sid[0].num_auths = als_sid[0].sid.num_auths;
-
- ptr_sid[0] = 1;
-
- /* send user alias query */
- if (samr_query_useraliases(cli, fnum,
- pol_dom,
- ptr_sid, als_sid, &num_aliases, &rid_mem))
- {
- uint32 num_names;
- char **name = NULL;
- uint32 *type = NULL;
-
- uint32 *rid_copy = (uint32*)malloc(num_aliases * sizeof(*rid_copy));
-
- if (rid_copy != NULL)
- {
- uint32 i;
- for (i = 0; i < num_aliases; i++)
- {
- rid_copy[i] = rid_mem[i];
- }
- if (samr_query_lookup_rids(cli, fnum,
- pol_dom, 0x3e8,
- num_aliases, rid_copy,
- &num_names, &name, &type))
- {
- usr_mem(domain, sid1,
- user_rid, user_name,
- num_names, rid_mem, name, type);
- }
- }
-
- free_char_array(num_names, name);
- if (type != NULL)
- {
- free(type);
- }
- }
-
- if (rid_mem != NULL)
- {
- free(rid_mem);
- rid_mem = NULL;
- }
-
- if (ptr_sid != NULL)
- {
- free(ptr_sid);
- ptr_sid = NULL;
- }
- if (als_sid != NULL)
- {
- free(als_sid);
- als_sid = NULL;
- }
-}
-
-/****************************************************************************
-experimental SAM users enum.
-****************************************************************************/
-int msrpc_sam_enum_users(struct cli_state *cli,
- const char* domain,
- const DOM_SID *sid1,
- const char* srv_name,
- struct acct_info **sam,
- uint32 *num_sam_entries,
- USER_FN(usr_fn),
- USER_INFO_FN(usr_inf_fn),
- USER_MEM_FN(usr_grp_fn),
- USER_MEM_FN(usr_als_fn))
-{
- uint16 fnum;
- DOM_SID sid_1_5_20;
- uint32 user_idx;
- BOOL res = True;
- BOOL res1 = True;
- BOOL res2 = True;
- uint32 start_idx = 0x0;
- uint16 unk_0 = 0x0;
- uint16 acb_mask = 0;
- uint16 unk_1 = 0x0;
- uint32 ace_perms = 0x304; /* access control permissions */
- uint32 status;
- POLICY_HND sam_pol;
- POLICY_HND pol_dom;
- POLICY_HND pol_blt;
-
- (*sam) = NULL;
- (*num_sam_entries) = 0;
-
- string_to_sid(&sid_1_5_20, "S-1-5-32");
-
- DEBUG(5,("Number of entries:%d unk_0:%04x acb_mask:%04x unk_1:%04x\n",
- start_idx, unk_0, acb_mask, unk_1));
-
- /* open SAMR session. negotiate credentials */
- res = res ? cli_nt_session_open(cli, PIPE_SAMR, &fnum) : False;
-
- /* establish a connection. */
- res = res ? samr_connect(cli, fnum,
- srv_name, 0x02000000,
- &sam_pol) : False;
-
- /* connect to the domain */
- res1 = res ? samr_open_domain(cli, fnum,
- &sam_pol, ace_perms, sid1,
- &pol_dom) : False;
-
- /* connect to the S-1-5-20 domain */
- res2 = res ? samr_open_domain(cli, fnum,
- &sam_pol, ace_perms, &sid_1_5_20,
- &pol_blt) : False;
-
- if (res1)
- {
- /* read some users */
- do
- {
- status = samr_enum_dom_users(cli, fnum,
- &pol_dom,
- &start_idx, acb_mask, unk_1, 0x100000,
- sam, num_sam_entries);
-
- } while (status == STATUS_MORE_ENTRIES);
-
- if ((*num_sam_entries) == 0)
- {
- report(out_hnd, "No users\n");
- }
-
- /* query all the users */
- for (user_idx = 0; res && user_idx <
- (*num_sam_entries); user_idx++)
- {
- uint32 user_rid = (*sam)[user_idx].rid;
- char *user_name = (*sam)[user_idx].acct_name;
-
- if (usr_fn != NULL)
- {
- usr_fn(domain, sid1, user_rid, user_name);
- }
-
- if (usr_inf_fn != NULL)
- {
- req_user_info(cli, fnum, &pol_dom,
- domain, sid1,
- user_rid,
- usr_inf_fn);
- }
-
- if (usr_grp_fn != NULL)
- {
- req_group_info(cli, fnum, &pol_dom,
- domain, sid1,
- user_rid, user_name,
- usr_grp_fn);
- }
-
- if (usr_als_fn != NULL)
- {
- req_alias_info(cli, fnum, &pol_dom,
- domain, sid1,
- user_rid, user_name,
- usr_als_fn);
- req_alias_info(cli, fnum, &pol_blt,
- domain, sid1,
- user_rid, user_name,
- usr_als_fn);
- }
- }
- }
-
- res2 = res2 ? samr_close(cli, fnum, &pol_blt) : False;
- res1 = res1 ? samr_close(cli, fnum, &pol_dom) : False;
- res = res ? samr_close(cli, fnum, &sam_pol) : False;
-
- /* close the session */
- cli_nt_session_close(cli, fnum);
-
- if (res)
- {
- DEBUG(5,("msrpc_sam_enum_users: succeeded\n"));
- }
- else
- {
- DEBUG(5,("msrpc_sam_enum_users: failed\n"));
- }
-
- return (*num_sam_entries);
-}
-
-
-/****************************************************************************
-experimental SAM domain info query.
-****************************************************************************/
-BOOL sam_query_dominfo(struct client_info *info, const DOM_SID *sid1,
- uint32 switch_value, SAM_UNK_CTR *ctr)
-{
- uint16 fnum;
- fstring srv_name;
- BOOL res = True;
- BOOL res1 = True;
- BOOL res2 = True;
- uint32 ace_perms = 0x02000000; /* absolutely no idea. */
- POLICY_HND sam_pol;
- POLICY_HND pol_dom;
-
- fstrcpy(srv_name, "\\\\");
- fstrcat(srv_name, info->dest_host);
- strupper(srv_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 */
- res1 = res ? samr_open_domain(smb_cli, fnum,
- &sam_pol, ace_perms, sid1,
- &pol_dom) : False;
-
- /* send a samr 0x8 command */
- res2 = res ? samr_query_dom_info(smb_cli, fnum,
- &pol_dom, switch_value, ctr) : False;
-
- res1 = res1 ? 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 (res2)
- {
- DEBUG(5,("sam_query_dominfo: succeeded\n"));
- }
- else
- {
- DEBUG(5,("sam_query_dominfo: failed\n"));
- }
-
- return res2;
-}
-
-
-static BOOL query_aliasinfo(struct cli_state *cli, uint16 fnum,
- const POLICY_HND *pol_dom,
- const char *domain,
- const DOM_SID *sid,
- uint32 alias_rid,
- ALIAS_INFO_FN(grp_inf))
-{
- ALIAS_INFO_CTR ctr;
-
- /* send alias info query */
- if (get_samr_query_aliasinfo(smb_cli, fnum,
- pol_dom,
- 3, /* info level */
- alias_rid, &ctr))
- {
- if (grp_inf != NULL)
- {
- grp_inf(domain, sid, alias_rid, &ctr);
- }
- return True;
- }
- return False;
-}
-
-BOOL sam_query_aliasmem(struct cli_state *cli, uint16 fnum,
- const POLICY_HND *pol_dom,
- uint32 alias_rid,
- uint32 *num_names,
- DOM_SID ***sids,
- char ***name,
- uint8 **type)
-{
- BOOL res3 = True;
- BOOL res4 = True;
- DOM_SID2 sid_mem[MAX_LOOKUP_SIDS];
- uint32 num_aliases = 0;
-
- *sids = NULL;
- *num_names = 0;
- *name = NULL;
- *type = NULL;
-
- /* get alias members */
- res3 = get_samr_query_aliasmem(smb_cli, fnum,
- pol_dom,
- alias_rid, &num_aliases, sid_mem);
-
- if (res3 && num_aliases != 0)
- {
- fstring srv_name;
- uint16 fnum_lsa;
- POLICY_HND lsa_pol;
-
- uint32 i;
- uint32 numsids = 0;
-
- fstrcpy(srv_name, "\\\\");
- fstrcat(srv_name, cli->desthost);
- strupper(srv_name);
-
- for (i = 0; i < num_aliases; i++)
- {
- add_sid_to_array(&numsids, sids, &sid_mem[i].sid);
- }
-
- /* open LSARPC session. */
- res3 = res3 ? cli_nt_session_open(smb_cli, PIPE_LSARPC, &fnum_lsa) : False;
-
- /* lookup domain controller; receive a policy handle */
- res3 = res3 ? lsa_open_policy(smb_cli, fnum_lsa,
- srv_name,
- &lsa_pol, True) : False;
-
- /* send lsa lookup sids call */
- res4 = res3 ? lsa_lookup_sids(smb_cli, fnum_lsa,
- &lsa_pol,
- num_aliases, *sids,
- name, type, num_names) : False;
-
- res3 = res3 ? lsa_close(smb_cli, fnum_lsa, &lsa_pol) : False;
-
- cli_nt_session_close(smb_cli, fnum_lsa);
- }
-
- if (!res4)
- {
- free_char_array(*num_names, *name);
- if ((*type) != NULL)
- {
- free(*type);
- }
- if ((*sids) != NULL)
- {
- free_sid_array(num_aliases, *sids);
- }
- *num_names = 0;
- *name = NULL;
- *type = NULL;
- *sids = NULL;
- }
-
- return res4;
-}
-
-static BOOL req_aliasmem_info(struct cli_state *cli, uint16 fnum,
- const POLICY_HND *pol_dom,
- const char *domain,
- const DOM_SID *sid,
- uint32 alias_rid,
- const char *alias_name,
- ALIAS_MEM_FN(als_mem))
-{
- uint32 num_names = 0;
- char **name = NULL;
- uint8 *type = NULL;
- DOM_SID **sids = NULL;
-
- if (sam_query_aliasmem(cli, fnum, pol_dom, alias_rid,
- &num_names, &sids,
- &name, &type))
- {
- als_mem(domain, sid,
- alias_rid, alias_name,
- num_names, sids, name, type);
-
- free_char_array(num_names, name);
- if (type != NULL)
- {
- free(type);
- }
- if (sids != NULL)
- {
- free_sid_array(num_names, sids);
- }
- return True;
- }
- return False;
-}
-
-BOOL sam_query_groupmem(struct cli_state *cli, uint16 fnum,
- const POLICY_HND *pol_dom,
- uint32 group_rid,
- uint32 *num_names,
- uint32 **rid_mem,
- char ***name,
- uint32 **type)
-{
- uint32 num_mem;
- uint32 *attr_mem = NULL;
- BOOL res3;
-
- *rid_mem = NULL;
- *num_names = 0;
- *name = NULL;
- *type = NULL;
-
- /* get group members */
- res3 = get_samr_query_groupmem(cli, fnum,
- pol_dom,
- group_rid, &num_mem, rid_mem, &attr_mem);
-
- if (res3 && num_mem != 0)
- {
- uint32 *rid_copy = (uint32*)malloc(num_mem *
- sizeof(rid_copy[0]));
-
- if (rid_copy != NULL)
- {
- uint32 i;
- for (i = 0; i < num_mem; i++)
- {
- rid_copy[i] = (*rid_mem)[i];
- }
- /* resolve names */
- res3 = samr_query_lookup_rids(cli, fnum,
- pol_dom, 1000,
- num_mem, rid_copy, num_names, name, type);
- }
- }
- else
- {
- if (attr_mem != NULL)
- {
- free(attr_mem);
- }
- if ((*rid_mem) != NULL)
- {
- free(*rid_mem);
- }
- attr_mem = NULL;
- *rid_mem = NULL;
- }
-
- if (!res3)
- {
- free_char_array(*num_names, *name);
- if ((*type) != NULL)
- {
- free(*type);
- }
- *num_names = 0;
- *name = NULL;
- *type = NULL;
- }
-
- if (attr_mem != NULL)
- {
- free(attr_mem);
- }
-
- return res3;
-}
-
-static BOOL query_groupinfo(struct cli_state *cli, uint16 fnum,
- const POLICY_HND *pol_dom,
- const char *domain,
- const DOM_SID *sid,
- uint32 group_rid,
- GROUP_INFO_FN(grp_inf))
-{
- GROUP_INFO_CTR ctr;
-
- /* send group info query */
- if (get_samr_query_groupinfo(smb_cli, fnum,
- pol_dom,
- 1, /* info level */
- group_rid, &ctr))
- {
- if (grp_inf != NULL)
- {
- grp_inf(domain, sid, group_rid, &ctr);
- }
- return True;
- }
- return False;
-}
-
-static BOOL req_groupmem_info(struct cli_state *cli, uint16 fnum,
- const POLICY_HND *pol_dom,
- const char *domain,
- const DOM_SID *sid,
- uint32 group_rid,
- const char *group_name,
- GROUP_MEM_FN(grp_mem))
-{
- uint32 num_names = 0;
- char **name = NULL;
- uint32 *type = NULL;
- uint32 *rid_mem = NULL;
-
- if (sam_query_groupmem(cli, fnum, pol_dom, group_rid,
- &num_names, &rid_mem, &name, &type))
- {
- grp_mem(domain, sid,
- group_rid, group_name,
- num_names, rid_mem, name, type);
-
- free_char_array(num_names, name);
- if (type != NULL)
- {
- free(type);
- }
- if (rid_mem != NULL)
- {
- free(rid_mem);
- }
- return True;
- }
- return False;
-}
-
-/****************************************************************************
-SAM Domains query.
- DOMAIN_INFO_FN(dom_inf_fn),
- DOMAIN_MEM_FN(dom_mem_fn))
-****************************************************************************/
-uint32 msrpc_sam_enum_domains(struct cli_state *cli,
- const char* srv_name,
- struct acct_info **sam,
- uint32 *num_sam_entries,
- DOMAIN_FN(dom_fn))
-{
- uint16 fnum;
- BOOL res = True;
- uint32 ace_perms = 0x02000000; /* access control permissions. */
- POLICY_HND sam_pol;
- uint32 status;
-
- /* open SAMR session. negotiate credentials */
- res = res ? cli_nt_session_open(cli, PIPE_SAMR, &fnum) : False;
-
- /* establish a connection. */
- res = res ? samr_connect(cli, fnum,
- srv_name, ace_perms,
- &sam_pol) : False;
-
- (*sam) = NULL;
- (*num_sam_entries) = 0;
-
- if (res)
- {
- uint32 domain_idx;
- uint32 start_idx = 0;
- /* read some domains */
- do
- {
- status = samr_enum_domains(cli, fnum,
- &sam_pol,
- &start_idx, 0x10000,
- sam, num_sam_entries);
-
- } while (status == STATUS_MORE_ENTRIES);
-
- if ((*num_sam_entries) == 0)
- {
- report(out_hnd, "No domains\n");
- }
-
- for (domain_idx = 0; domain_idx < (*num_sam_entries); domain_idx++)
- {
- char *domain_name = (*sam)[domain_idx].acct_name;
-
- if (dom_fn != NULL)
- {
- dom_fn(domain_name);
- }
-
-#if 0
- if (dom_inf_fn != NULL)
- {
- query_domaininfo(cli, fnum, &sam_pol,
- domain_name,
- dom_inf_fn);
- }
- if (dom_mem_fn != NULL)
- {
- req_domainmem_info(cli, fnum, &sam_pol,
- domain_name,
- dom_mem_fn);
- }
-#endif
- }
- }
-
- res = res ? samr_close(cli, fnum, &sam_pol) : False;
-
- /* close the session */
- cli_nt_session_close(cli, fnum);
-
- if (res)
- {
- DEBUG(5,("msrpc_sam_enum_domains: succeeded\n"));
- }
- else
- {
- DEBUG(5,("msrpc_sam_enum_domains: failed\n"));
- }
- return (*num_sam_entries);
-}
-
-/****************************************************************************
-SAM groups query.
-****************************************************************************/
-uint32 msrpc_sam_enum_groups(struct cli_state *cli,
- const char* domain,
- const DOM_SID *sid1,
- const char* srv_name,
- struct acct_info **sam,
- uint32 *num_sam_entries,
- GROUP_FN(grp_fn),
- GROUP_INFO_FN(grp_inf_fn),
- GROUP_MEM_FN(grp_mem_fn))
-{
- uint16 fnum;
- BOOL res = True;
- uint32 ace_perms = 0x02000000; /* access control permissions. */
- POLICY_HND sam_pol;
- POLICY_HND pol_dom;
- uint32 status;
-
- /* open SAMR session. negotiate credentials */
- res = res ? cli_nt_session_open(cli, PIPE_SAMR, &fnum) : False;
-
- /* establish a connection. */
- res = res ? samr_connect(cli, fnum,
- srv_name, 0x02000000,
- &sam_pol) : False;
-
- /* connect to the domain */
- res = res ? samr_open_domain(cli, fnum,
- &sam_pol, ace_perms, sid1,
- &pol_dom) : False;
-
- (*sam) = NULL;
- (*num_sam_entries) = 0;
-
- if (res)
- {
- uint32 group_idx;
- uint32 start_idx = 0;
- /* read some groups */
- do
- {
- status = samr_enum_dom_groups(cli, fnum,
- &pol_dom,
- &start_idx, 0x100000,
- sam, num_sam_entries);
-
- } while (status == STATUS_MORE_ENTRIES);
-
- if ((*num_sam_entries) == 0)
- {
- report(out_hnd, "No groups\n");
- }
-
- for (group_idx = 0; group_idx < (*num_sam_entries); group_idx++)
- {
- uint32 group_rid = (*sam)[group_idx].rid;
- char *group_name = (*sam)[group_idx].acct_name;
-
- if (grp_fn != NULL)
- {
- grp_fn(domain, sid1, group_rid, group_name);
- }
-
- if (grp_inf_fn != NULL)
- {
- query_groupinfo(cli, fnum, &pol_dom,
- domain, sid1,
- group_rid,
- grp_inf_fn);
- }
- if (grp_mem_fn != NULL)
- {
- req_groupmem_info(cli, fnum, &pol_dom,
- domain, sid1,
- group_rid, group_name,
- grp_mem_fn);
- }
- }
- }
-
- res = res ? samr_close(cli, fnum, &pol_dom) : False;
- res = res ? samr_close(cli, fnum, &sam_pol) : False;
-
- /* close the session */
- cli_nt_session_close(cli, fnum);
-
- if (res)
- {
- DEBUG(5,("msrpc_sam_enum_groups: succeeded\n"));
- }
- else
- {
- DEBUG(5,("msrpc_sam_enum_groups: failed\n"));
- }
- return (*num_sam_entries);
-}
-
-/****************************************************************************
-SAM aliases query.
-****************************************************************************/
-uint32 msrpc_sam_enum_aliases(struct cli_state *cli,
- const char* domain,
- const DOM_SID *sid1,
- const char* srv_name,
- struct acct_info **sam,
- uint32 *num_sam_entries,
- ALIAS_FN(als_fn),
- ALIAS_INFO_FN(als_inf_fn),
- ALIAS_MEM_FN(als_mem_fn))
-{
- uint16 fnum;
- BOOL res = True;
- uint32 ace_perms = 0x02000000; /* access control permissions */
- POLICY_HND sam_pol;
- POLICY_HND pol_dom;
- uint32 status = 0x0;
-
- /* open SAMR session. negotiate credentials */
- res = res ? cli_nt_session_open(cli, PIPE_SAMR, &fnum) : False;
-
- /* establish a connection. */
- res = res ? samr_connect(cli, fnum,
- srv_name, 0x02000000,
- &sam_pol) : False;
-
- /* connect to the domain */
- res = res ? samr_open_domain(cli, fnum,
- &sam_pol, ace_perms, sid1,
- &pol_dom) : False;
-
- (*sam) = NULL;
- (*num_sam_entries) = 0;
-
- if (res)
- {
- uint32 alias_idx;
- uint32 start_idx = 0;
- /* read some groups */
- do
- {
- status = samr_enum_dom_aliases(cli, fnum,
- &pol_dom,
- &start_idx, 0x100000,
- sam, num_sam_entries);
-
- } while (status == STATUS_MORE_ENTRIES);
-
- if ((*num_sam_entries) == 0)
- {
- report(out_hnd, "No aliases\n");
- }
-
- for (alias_idx = 0; alias_idx < (*num_sam_entries); alias_idx++)
- {
- uint32 alias_rid = (*sam)[alias_idx].rid;
- char *alias_name = (*sam)[alias_idx].acct_name;
-
- if (als_fn != NULL)
- {
- als_fn(domain, sid1, alias_rid, alias_name);
- }
-
- if (als_inf_fn != NULL)
- {
- query_aliasinfo(cli, fnum, &pol_dom,
- domain, sid1,
- alias_rid,
- als_inf_fn);
- }
- if (als_mem_fn != NULL)
- {
- req_aliasmem_info(cli, fnum, &pol_dom,
- domain, sid1,
- alias_rid, alias_name,
- als_mem_fn);
- }
- }
- }
-
- res = res ? samr_close(cli, fnum, &sam_pol) : False;
- res = res ? samr_close(cli, fnum, &pol_dom) : False;
-
- /* close the session */
- cli_nt_session_close(cli, fnum);
-
- if (res)
- {
- DEBUG(5,("msrpc_sam_enum_aliases: succeeded\n"));
- }
- else
- {
- DEBUG(5,("msrpc_sam_enum_aliases: failed\n"));
- }
-
- return (*num_sam_entries);
-}
/****************************************************************************
SAM password change