Rework SAMR code, and remove rpc_parse dependency on passdb

Andrew Bartlett abartlet at samba.org
Tue Jun 25 20:51:03 GMT 2002


Kai Krueger wrote:
> 
> From: "Andrew Bartlett" <abartlet at samba.org> Sent: Tuesday, June 25, 2002 4:33 PM
> 
> > I've been doing some cleanup work recently - and I've particulary been
> > attacking the complex web of samba dependencies.
> >
> > This patch does two things:  It reworks some SAMR code, in a way that
> > avoids the need for *two* sepeate 'enumuerate a list of domain users'
> > functions, and
> > that adds some SID checkings.
> >
> > Now the sid checking is currently incorrect - I'm still chasing down the
> > finer details of 'policy handles', but I just wanted to put this patch
> > out for an eyeball.
> >
> > What do people think - are there other problems with what I'm doing?
> >
> > And can anybody explain to me how policy handles work?
> 
> Each time a client opens a SAM-object (i.e. domain, user ...) the
> serversided open function creates a new handle that is a link to some server
> stored data. Usually this data is about the object that is being open (e.g. SID,
> access rights ...) but can basically be anything. The handle is returned to the
> client which passes it back to the server in the next functions on that SAM-object.
> The server uses this handle to lookup the originally stored date and identify the
> object.

Thanks for that - it's now a bit clearer.

> >  In particular I
> > want to find the policy for the domain that this user was opened on - so
> > I can check the domain sid during the reply.  (Yes, I could assume the
> > passdb is sane, and gives back correct sids, but I want the extra check
> > before I strip the rid from the sid).
> 
> It is possible to store the domain policy handle in the user policy, so that you
> can get the domain policy on which the user was opened if you have the user
> policy. I'm not sure if that is a good idea though, because the domain policy
> might already be closed even though the user policy is still open. The information
> you need about the user should rather be stored with the user policy.
> Look at the samr_info struct to see what is currently stored with the policy.
> This includes the SID, so it is easy to split off the domain sid from the user SID.

Thats how I've done it.  Thanks for the warning on the dangling policy
pointer issue.

> It would be good, if all those q_u->pol could be renamed to identify on what
> type of sam-object each of the policies where opened. i.e. q_u->domain_pol,
> q_u->user_pol, q_u->group_pol and so on. I think that would clarify some of
> the policy stuff.

Yes, I would support that.  Patches welcome ;-)

> >+ if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
> >  return NT_STATUS_INVALID_HANDLE;
> >
> >+ if (!get_lsa_policy_samr_sid(p, &q_u->pol, &domain_sid))
> >+ return NT_STATUS_INVALID_HANDLE;
> >+
> 
> Why do you need both find_policy_by_hnd() and get_lsa_policy_samr_sid()?
> The second calls the first, so you should only need one of them.

Fixed.

> I haven't looked at the changes very close yet, but wouldn't a lot of this
> need to be changed again after the samdb rework we are planning on IRC?
> Wouldn't it be more sensible to do this stuff after or while the reworking?

Not really, most of this will stay the same - get a list of
SAM_ACCOUNTS, and send to wire somehow, so getting this end into shape
doesn't conflict as far as I can tell.  It should make actually
implementing the rewrite slightly sane however.

I've tested this pew patch against TNG's rpcclient (which implements the
enum_users call) and it seems to work, but I really need to check with
Win2k and a large number of users.  (see if the paging is correct).

Andrew Bartlett

-- 
Andrew Bartlett                                 abartlet at pcug.org.au
Manager, Authentication Subsystems, Samba Team  abartlet at samba.org
Student Network Administrator, Hawker College   abartlet at hawkerc.net
http://samba.org     http://build.samba.org     http://hawkerc.net
-------------- next part --------------
? config.h.in
? docs/docbook/confdefs.h
? source/Makefile.in-
? source/config.abartlet
? source/nt_pwd
? source/auth/auth_ntlmssp.c
? source/include/nmbd_dhcp_for_wins.h
? source/include/smb_interactive.h
? source/intl/Makefile
? source/intl/po
? source/intl/po2tbl.sed
? source/libsmb/.new.cliprint.
? source/nmbd/nmbd_dhcp_for_wins.c
? source/nsswitch/.libs
? source/nsswitch/ntlmauth.c
? source/passdb/pdb_compat.c
? source/po/Makefile
? source/po/POTFILES
? source/rpc_server/srv_samr_util.c
? source/torture/map_extract.c
Index: source/Makefile.in
===================================================================
RCS file: /data/cvs/samba/source/Makefile.in,v
retrieving revision 1.490
diff -u -r1.490 Makefile.in
--- source/Makefile.in	2002/06/25 13:18:09	1.490
+++ source/Makefile.in	2002/06/26 03:24:20
@@ -166,15 +166,17 @@
 
 LIBMSRPC_OBJ = libsmb/cli_lsarpc.o libsmb/cli_samr.o libsmb/cli_spoolss.o \
 	       libsmb/cli_netlogon.o libsmb/cli_srvsvc.o libsmb/cli_wkssvc.o \
-	       libsmb/cli_dfs.o libsmb/cli_reg.o libsmb/trust_passwd.o\
+	       libsmb/cli_dfs.o libsmb/cli_reg.o \
 	       rpc_client/cli_pipe.o
 
+LIBMSRPC_SERVER_OBJ = libsmb/trust_passwd.o
+
 LIBMSRPC_PICOBJ = $(LIBMSRPC_OBJ:.o=.po)
 
 RPC_SERVER_OBJ = rpc_server/srv_lsa.o rpc_server/srv_lsa_nt.o \
                  rpc_server/srv_lsa_hnd.o rpc_server/srv_netlog.o rpc_server/srv_netlog_nt.o \
                  rpc_server/srv_pipe_hnd.o rpc_server/srv_reg.o rpc_server/srv_reg_nt.o \
-                 rpc_server/srv_samr.o rpc_server/srv_samr_nt.o \
+                 rpc_server/srv_samr.o rpc_server/srv_samr_nt.o rpc_server/srv_samr_util.o \
 		 rpc_server/srv_srvsvc.o rpc_server/srv_srvsvc_nt.o \
                  rpc_server/srv_util.o rpc_server/srv_wkssvc.o rpc_server/srv_wkssvc_nt.o \
                  rpc_server/srv_pipe.o rpc_server/srv_dfs.o rpc_server/srv_dfs_nt.o \
@@ -202,7 +204,8 @@
 PASSDB_OBJ = $(PASSDB_GET_SET_OBJ) passdb/passdb.o passdb/pdb_interface.o \
 		passdb/machine_sid.o passdb/pdb_smbpasswd.o \
 		passdb/pdb_tdb.o passdb/pdb_ldap.o passdb/pdb_plugin.o \
-		passdb/pdb_nisplus.o passdb/pdb_unix.o passdb/util_sam_sid.o 
+		passdb/pdb_nisplus.o passdb/pdb_unix.o passdb/util_sam_sid.o \
+		passdb/pdb_compat.o
 
 GROUPDB_OBJ = groupdb/mapping.o
 
@@ -254,7 +257,8 @@
            $(RPC_SERVER_OBJ) $(RPC_PARSE_OBJ) $(SECRETS_OBJ) \
            $(LOCKING_OBJ) $(PASSDB_OBJ) $(PRINTING_OBJ) $(PROFILE_OBJ) \
 	   $(LIB_OBJ) $(PRINTBACKEND_OBJ) $(QUOTAOBJS) $(OPLOCK_OBJ) \
-	   $(NOTIFY_OBJ) $(GROUPDB_OBJ) $(AUTH_OBJ) $(LIBMSRPC_OBJ) \
+	   $(NOTIFY_OBJ) $(GROUPDB_OBJ) $(AUTH_OBJ) \
+	   $(LIBMSRPC_OBJ) $(LIBMSRPC_SERVER_OBJ) \
 	   $(LIBADS_OBJ) $(LIBADS_SERVER_OBJ)
 
 
@@ -362,12 +366,12 @@
 	   utils/net_rap.o utils/net_rpc.o \
 	   utils/net_rpc_join.o utils/net_time.o utils/net_lookup.o
 
-NET_OBJ = $(NET_OBJ1) $(SECRETS_OBJ) $(PASSDB_OBJ) $(GROUPDB_OBJ) \
-	  $(LIBSMB_OBJ) $(LIBMSRPC_OBJ) $(RPC_PARSE_OBJ) \
+NET_OBJ = $(NET_OBJ1) $(SECRETS_OBJ) $(LIBSMB_OBJ) \
+	  $(RPC_PARSE_OBJ) $(PASSDB_GET_SET_OBJ) \
 	  $(PARAM_OBJ) $(UBIQX_OBJ) $(LIB_OBJ) \
+	  $(LIBMSRPC_OBJ) $(LIBMSRPC_SERVER_OBJ) \
 	  $(LIBADS_OBJ) $(LIBADS_SERVER_OBJ)
 
-
 CUPS_OBJ = client/smbspool.o $(PARAM_OBJ) $(LIBSMB_OBJ) $(UBIQX_OBJ) $(LIB_OBJ) 
 
 MOUNT_OBJ = client/smbmount.o \
@@ -404,8 +408,8 @@
                  $(UBIQX_OBJ) $(LIB_OBJ)
 
 SMBCACLS_OBJ = utils/smbcacls.o $(LOCKING_OBJ) $(LIBSMB_OBJ) $(PARAM_OBJ) \
-                 $(UBIQX_OBJ) $(LIB_OBJ) $(RPC_PARSE_OBJ) $(PASSDB_OBJ) \
-		 $(LIBMSRPC_OBJ) $(GROUPDB_OBJ) $(SECRETS_OBJ)
+                 $(UBIQX_OBJ) $(LIB_OBJ) $(RPC_PARSE_OBJ) $(PASSDB_GET_SET_OBJ) \
+		 $(LIBMSRPC_OBJ) 
 
 TALLOCTORT_OBJ = lib/talloctort.o  $(LIB_OBJ) $(PARAM_OBJ) $(UBIQX_OBJ)
 
@@ -430,7 +434,7 @@
 	    $(AUTH_OBJ) $(PARAM_OBJ) $(LOCKING_OBJ) $(SECRETS_OBJ) \
 	    $(PRINTING_OBJ) $(PRINTBACKEND_OBJ) $(OPLOCK_OBJ) $(NOTIFY_OBJ) \
 	    $(QUOTAOBJS) $(PASSDB_OBJ) $(GROUPDB_OBJ) $(MSDFS_OBJ) $(READLINE_OBJ) \
-	    $(PROFILE_OBJ) $(LIBADS_OBJ) $(LIBADS_SERVER_OBJ)
+	    $(PROFILE_OBJ)
 
 NSS_OBJ_0 = nsswitch/wins.o $(PARAM_OBJ) $(UBIQX_OBJ) $(LIBSMB_OBJ) $(LIB_OBJ) $(NSSWINS_OBJ)
 NSS_OBJ = $(NSS_OBJ_0:.o=.po)
@@ -471,7 +475,7 @@
 		nsswitch/winbindd_dual.o
 
 WINBINDD_OBJ = \
-		$(WINBINDD_OBJ1) $(PASSDB_OBJ) $(GROUPDB_OBJ) \
+		$(WINBINDD_OBJ1) $(PASSDB_GET_SET_OBJ) \
 		$(LIBNMB_OBJ) $(PARAM_OBJ) $(UBIQX_OBJ) $(LIB_OBJ) \
 		$(LIBSMB_OBJ) $(LIBMSRPC_OBJ) $(RPC_PARSE_OBJ) \
 		$(PROFILE_OBJ) $(UNIGRP_OBJ) \
Index: source/passdb/passdb.c
===================================================================
RCS file: /data/cvs/samba/source/passdb/passdb.c,v
retrieving revision 1.161
diff -u -r1.161 passdb.c
--- source/passdb/passdb.c	2002/06/14 04:26:23	1.161
+++ source/passdb/passdb.c	2002/06/26 03:24:30
@@ -937,122 +937,6 @@
 }
 
 /*************************************************************
- Copies a SAM_USER_INFO_23 to a SAM_ACCOUNT
- **************************************************************/
-
-void copy_id23_to_sam_passwd(SAM_ACCOUNT *to, SAM_USER_INFO_23 *from)
-{
-
-	if (from == NULL || to == NULL) 
-		return;
-
-	pdb_set_logon_time(to,nt_time_to_unix(&from->logon_time), True);
-	pdb_set_logoff_time(to,nt_time_to_unix(&from->logoff_time), True);
-	pdb_set_kickoff_time(to, nt_time_to_unix(&from->kickoff_time), True);
-	pdb_set_pass_can_change_time(to, nt_time_to_unix(&from->pass_can_change_time), True);
-	pdb_set_pass_must_change_time(to, nt_time_to_unix(&from->pass_must_change_time), True);
-
-	pdb_set_pass_last_set_time(to, nt_time_to_unix(&from->pass_last_set_time));
-
-	if (from->uni_user_name.buffer)
-		pdb_set_username(to      , pdb_unistr2_convert(&from->uni_user_name   ));
-	if (from->uni_full_name.buffer)
-		pdb_set_fullname(to      , pdb_unistr2_convert(&from->uni_full_name   ));
-	if (from->uni_home_dir.buffer)
-		pdb_set_homedir(to       , pdb_unistr2_convert(&from->uni_home_dir    ), True);
-	if (from->uni_dir_drive.buffer)
-		pdb_set_dir_drive(to     , pdb_unistr2_convert(&from->uni_dir_drive   ), True);
-	if (from->uni_logon_script.buffer)
-		pdb_set_logon_script(to  , pdb_unistr2_convert(&from->uni_logon_script), True);
-	if (from->uni_profile_path.buffer)
-		pdb_set_profile_path(to  , pdb_unistr2_convert(&from->uni_profile_path), True);
-	if (from->uni_acct_desc.buffer)
-		pdb_set_acct_desc(to     , pdb_unistr2_convert(&from->uni_acct_desc   ));
-	if (from->uni_workstations.buffer)
-		pdb_set_workstations(to  , pdb_unistr2_convert(&from->uni_workstations));
-	if (from->uni_unknown_str.buffer)
-		pdb_set_unknown_str(to   , pdb_unistr2_convert(&from->uni_unknown_str ));
-	if (from->uni_munged_dial.buffer)
-		pdb_set_munged_dial(to   , pdb_unistr2_convert(&from->uni_munged_dial ));
-
-	if (from->user_rid)
-		pdb_set_user_sid_from_rid(to, from->user_rid);
-	if (from->group_rid)
-		pdb_set_group_sid_from_rid(to, from->group_rid);
-
-	pdb_set_acct_ctrl(to, from->acb_info);
-	pdb_set_unknown_3(to, from->unknown_3);
-
-	pdb_set_logon_divs(to, from->logon_divs);
-	pdb_set_hours_len(to, from->logon_hrs.len);
-	pdb_set_hours(to, from->logon_hrs.hours);
-
-	pdb_set_unknown_5(to, from->unknown_5);
-	pdb_set_unknown_6(to, from->unknown_6);
-}
-
-
-/*************************************************************
- Copies a sam passwd.
- **************************************************************/
-
-void copy_id21_to_sam_passwd(SAM_ACCOUNT *to, SAM_USER_INFO_21 *from)
-{
-	if (from == NULL || to == NULL) 
-		return;
-
-	pdb_set_logon_time(to,nt_time_to_unix(&from->logon_time), True);
-	pdb_set_logoff_time(to,nt_time_to_unix(&from->logoff_time), True);
-	pdb_set_kickoff_time(to, nt_time_to_unix(&from->kickoff_time), True);
-	pdb_set_pass_can_change_time(to, nt_time_to_unix(&from->pass_can_change_time), True);
-	pdb_set_pass_must_change_time(to, nt_time_to_unix(&from->pass_must_change_time), True);
-
-	pdb_set_pass_last_set_time(to, nt_time_to_unix(&from->pass_last_set_time));
-
-	if (from->uni_user_name.buffer)
-		pdb_set_username(to      , pdb_unistr2_convert(&from->uni_user_name   ));
-	if (from->uni_full_name.buffer)
-		pdb_set_fullname(to      , pdb_unistr2_convert(&from->uni_full_name   ));
-	if (from->uni_home_dir.buffer)
-		pdb_set_homedir(to       , pdb_unistr2_convert(&from->uni_home_dir    ), True);
-	if (from->uni_dir_drive.buffer)
-		pdb_set_dir_drive(to     , pdb_unistr2_convert(&from->uni_dir_drive   ), True);
-	if (from->uni_logon_script.buffer)
-		pdb_set_logon_script(to  , pdb_unistr2_convert(&from->uni_logon_script), True);
-	if (from->uni_profile_path.buffer)
-		pdb_set_profile_path(to  , pdb_unistr2_convert(&from->uni_profile_path), True);
-	if (from->uni_acct_desc.buffer)
-		pdb_set_acct_desc(to     , pdb_unistr2_convert(&from->uni_acct_desc   ));
-	if (from->uni_workstations.buffer)
-		pdb_set_workstations(to  , pdb_unistr2_convert(&from->uni_workstations));
-	if (from->uni_unknown_str.buffer)
-		pdb_set_unknown_str(to   , pdb_unistr2_convert(&from->uni_unknown_str ));
-	if (from->uni_munged_dial.buffer)
-		pdb_set_munged_dial(to   , pdb_unistr2_convert(&from->uni_munged_dial ));
-
-	if (from->user_rid)
-		pdb_set_user_sid_from_rid(to, from->user_rid);
-	if (from->group_rid)
-		pdb_set_group_sid_from_rid(to, from->group_rid);
-
-	/* FIXME!!  Do we need to copy the passwords here as well?
-	   I don't know.  Need to figure this out   --jerry */
-
-	/* Passwords dealt with in caller --abartlet */
-
-	pdb_set_acct_ctrl(to, from->acb_info);
-	pdb_set_unknown_3(to, from->unknown_3);
-
-	pdb_set_logon_divs(to, from->logon_divs);
-	pdb_set_hours_len(to, from->logon_hrs.len);
-	pdb_set_hours(to, from->logon_hrs.hours);
-
-	pdb_set_unknown_5(to, from->unknown_5);
-	pdb_set_unknown_6(to, from->unknown_6);
-}
-
-
-/*************************************************************
  Change a password entry in the local smbpasswd file.
 
  FIXME!!  The function needs to be abstracted into the
Index: source/passdb/pdb_get_set.c
===================================================================
RCS file: /data/cvs/samba/source/passdb/pdb_get_set.c,v
retrieving revision 1.14
diff -u -r1.14 pdb_get_set.c
--- source/passdb/pdb_get_set.c	2002/06/15 12:38:12	1.14
+++ source/passdb/pdb_get_set.c	2002/06/26 03:24:30
@@ -172,27 +172,6 @@
 		return (NULL);
 }	
 
-uint32 pdb_get_user_rid (const SAM_ACCOUNT *sampass)
-{
-	uint32 u_rid;
-
-	if (sampass)
-		if (sid_peek_check_rid(get_global_sam_sid(), pdb_get_user_sid(sampass),&u_rid))
-			return u_rid;
-	
-	return (0);
-}
-
-uint32 pdb_get_group_rid (const SAM_ACCOUNT *sampass)
-{
-	uint32 g_rid;
-
-	if (sampass)
-		if (sid_peek_check_rid(get_global_sam_sid(), pdb_get_group_sid(sampass),&g_rid))
-			return g_rid;
-	return (0);
-}
-
 /**
  * Get flags showing what is initalised in the SAM_ACCOUNT
  * @param sampass the SAM_ACCOUNT in question
@@ -574,60 +553,6 @@
 		DEBUG(1, ("pdb_set_group_sid_from_string: could not set sid %s on SAM_ACCOUNT!\n", g_sid));
 		return False;
 	}
-	return True;
-}
-
-BOOL pdb_set_user_sid_from_rid (SAM_ACCOUNT *sampass, uint32 rid)
-{
-	DOM_SID u_sid;
-	const DOM_SID *global_sam_sid;
-	
-	if (!sampass)
-		return False;
-
-	if (!(global_sam_sid = get_global_sam_sid())) {
-		DEBUG(1, ("pdb_set_user_sid_from_rid: Could not read global sam sid!\n"));
-		return False;
-	}
-
-	sid_copy(&u_sid, global_sam_sid);
-
-	if (!sid_append_rid(&u_sid, rid))
-		return False;
-
-	if (!pdb_set_user_sid(sampass, &u_sid))
-		return False;
-
-	DEBUG(10, ("pdb_set_user_sid_from_rid:\n\tsetting user sid %s from rid %d\n", 
-		    sid_string_static(&u_sid),rid));
-
-	return True;
-}
-
-BOOL pdb_set_group_sid_from_rid (SAM_ACCOUNT *sampass, uint32 grid)
-{
-	DOM_SID g_sid;
-	const DOM_SID *global_sam_sid;
-
-	if (!sampass)
-		return False;
-	
-	if (!(global_sam_sid = get_global_sam_sid())) {
-		DEBUG(1, ("pdb_set_user_sid_from_rid: Could not read global sam sid!\n"));
-		return False;
-	}
-
-	sid_copy(&g_sid, global_sam_sid);
-	
-	if (!sid_append_rid(&g_sid, grid))
-		return False;
-
-	if (!pdb_set_group_sid(sampass, &g_sid))
-		return False;
-
-	DEBUG(10, ("pdb_set_group_sid_from_rid:\n\tsetting group sid %s from rid %d\n", 
-		    sid_string_static(&g_sid), grid));
-
 	return True;
 }
 
Index: source/rpc_parse/parse_samr.c
===================================================================
RCS file: /data/cvs/samba/source/rpc_parse/parse_samr.c,v
retrieving revision 1.148
diff -u -r1.148 parse_samr.c
--- source/rpc_parse/parse_samr.c	2002/06/18 09:20:10	1.148
+++ source/rpc_parse/parse_samr.c	2002/06/26 03:24:31
@@ -1440,7 +1440,8 @@
 ********************************************************************/
 
 NTSTATUS init_sam_dispinfo_1(TALLOC_CTX *ctx, SAM_DISPINFO_1 *sam, uint32 num_entries,
-			 uint32 start_idx, DISP_USER_INFO *disp_user_info)
+			     uint32 start_idx, DISP_USER_INFO *disp_user_info,
+			     DOM_SID *domain_sid)
 {
 	uint32 len_sam_name, len_sam_full, len_sam_desc;
 	uint32 i;
@@ -1468,6 +1469,9 @@
 		const char *username;
 		const char *fullname;
 		const char *acct_desc;
+		uint32 user_rid;
+		const DOM_SID *user_sid;
+		fstring user_sid_string, domain_sid_string;			
 
 		DEBUG(11, ("init_sam_dispinfo_1: entry: %d\n",i));
 		
@@ -1486,14 +1490,25 @@
 		if (!acct_desc) 
 			acct_desc = "";
 
+		user_sid = pdb_get_user_sid(pwd);
+
+		if (!sid_peek_check_rid(domain_sid, user_sid, &user_rid)) {
+			DEBUG(0, ("init_sam_dispinfo_1: User %s has SID %s, which conflicts with "
+				  "the domain sid %s.  Failing operation.\n", 
+				  username, 
+				  sid_to_string(user_sid_string, user_sid),
+				  sid_to_string(domain_sid_string, domain_sid)));
+			return NT_STATUS_UNSUCCESSFUL;
+		}
+			
 		len_sam_name = strlen(username);
 		len_sam_full = strlen(fullname);
 		len_sam_desc = strlen(acct_desc);
 
 		init_sam_entry1(&sam->sam[i], start_idx + i + 1,
 				len_sam_name, len_sam_full, len_sam_desc,
-				pdb_get_user_rid(pwd), pdb_get_acct_ctrl(pwd));
-
+				user_rid, pdb_get_acct_ctrl(pwd));
+		
 		ZERO_STRUCTP(&sam->str[i].uni_acct_name);
 		ZERO_STRUCTP(&sam->str[i].uni_full_name);
 		ZERO_STRUCTP(&sam->str[i].uni_acct_desc);
@@ -1560,7 +1575,8 @@
 ********************************************************************/
 
 NTSTATUS init_sam_dispinfo_2(TALLOC_CTX *ctx, SAM_DISPINFO_2 *sam, uint32 num_entries,
-			 uint32 start_idx, DISP_USER_INFO *disp_user_info)
+			     uint32 start_idx, DISP_USER_INFO *disp_user_info, 
+			     DOM_SID *domain_sid )
 {
 	uint32 len_sam_name, len_sam_desc;
 	uint32 i;
@@ -1583,20 +1599,39 @@
 	ZERO_STRUCTP(sam->str);
 
 	for (i = 0; i < num_entries; i++) {
+		uint32 user_rid;
+		const DOM_SID *user_sid;
+		const char *username;
+		const char *acct_desc;
+		fstring user_sid_string, domain_sid_string;			
+
 		DEBUG(11, ("init_sam_dispinfo_2: entry: %d\n",i));
 		pwd=disp_user_info[i+start_idx].sam;
 
-		len_sam_name = strlen(pdb_get_username(pwd));
-		len_sam_desc = strlen(pdb_get_acct_desc(pwd));
+		username = pdb_get_username(pwd);
+		acct_desc = pdb_get_acct_desc(pwd);
+		user_sid = pdb_get_user_sid(pwd);
+
+		if (!sid_peek_check_rid(domain_sid, user_sid, &user_rid)) {
+			DEBUG(0, ("init_sam_dispinfo_2: User %s has SID %s, which conflicts with "
+				  "the domain sid %s.  Failing operation.\n", 
+				  username, 
+				  sid_to_string(user_sid_string, user_sid),
+				  sid_to_string(domain_sid_string, domain_sid)));
+			return NT_STATUS_UNSUCCESSFUL;
+		}
+			
+		len_sam_name = strlen(username);
+		len_sam_desc = strlen(acct_desc);
 	  
 		init_sam_entry2(&sam->sam[i], start_idx + i + 1,
 			  len_sam_name, len_sam_desc,
-			  pdb_get_user_rid(pwd), pdb_get_acct_ctrl(pwd));
+			  user_rid, pdb_get_acct_ctrl(pwd));
 	  
 		ZERO_STRUCTP(&sam->str[i].uni_srv_name);
 		ZERO_STRUCTP(&sam->str[i].uni_srv_desc);
 
-		init_unistr2(&sam->str[i].uni_srv_name, pdb_get_username(pwd),  len_sam_name);
+		init_unistr2(&sam->str[i].uni_srv_name, username,  len_sam_name);
 		init_unistr2(&sam->str[i].uni_srv_desc, pdb_get_acct_desc(pwd), len_sam_desc);
 	}
 
@@ -5844,7 +5879,7 @@
 
  *************************************************************************/
 
-void init_sam_user_info21A(SAM_USER_INFO_21 *usr, SAM_ACCOUNT *pw)
+NTSTATUS init_sam_user_info21A(SAM_USER_INFO_21 *usr, SAM_ACCOUNT *pw, DOM_SID *domain_sid)
 {
 	NTTIME 		logon_time, logoff_time, kickoff_time,
 			pass_last_set_time, pass_can_change_time,
@@ -5865,6 +5900,12 @@
 	const char*		workstations = pdb_get_workstations(pw);
 	const char*		munged_dial = pdb_get_munged_dial(pw);
 
+	uint32 user_rid;
+	const DOM_SID *user_sid;
+
+	uint32 group_rid;
+	const DOM_SID *group_sid;
+
 	len_user_name    = user_name    != NULL ? strlen(user_name   )+1 : 0;
 	len_full_name    = full_name    != NULL ? strlen(full_name   )+1 : 0;
 	len_home_dir     = home_dir     != NULL ? strlen(home_dir    )+1 : 0;
@@ -5906,9 +5947,35 @@
 
 	ZERO_STRUCT(usr->nt_pwd);
 	ZERO_STRUCT(usr->lm_pwd);
+
+	user_sid = pdb_get_user_sid(pw);
+	
+	if (!sid_peek_check_rid(domain_sid, user_sid, &user_rid)) {
+		fstring user_sid_string;
+		fstring domain_sid_string;
+		DEBUG(0, ("init_sam_user_info_21A: User %s has SID %s, \nwhich conflicts with "
+			  "the domain sid %s.  Failing operation.\n", 
+			  user_name, 
+			  sid_to_string(user_sid_string, user_sid),
+			  sid_to_string(domain_sid_string, domain_sid)));
+		return NT_STATUS_UNSUCCESSFUL;
+	}
+
+	group_sid = pdb_get_group_sid(pw);
+	
+	if (!sid_peek_check_rid(domain_sid, group_sid, &group_rid)) {
+		fstring group_sid_string;
+		fstring domain_sid_string;
+		DEBUG(0, ("init_sam_user_info_21A: User %s has Primary Group SID %s, \n"
+			  "which conflicts with the domain sid %s.  Failing operation.\n", 
+			  user_name, 
+			  sid_to_string(group_sid_string, group_sid),
+			  sid_to_string(domain_sid_string, domain_sid)));
+		return NT_STATUS_UNSUCCESSFUL;
+	}
 
-	usr->user_rid  = pdb_get_user_rid(pw);
-	usr->group_rid = pdb_get_group_rid(pw);
+	usr->user_rid  = user_rid;
+	usr->group_rid = group_rid;
 	usr->acb_info  = pdb_get_acct_ctrl(pw);
 	usr->unknown_3 = pdb_get_unknown3(pw);
 
@@ -5937,6 +6004,8 @@
 		memcpy(&usr->logon_hrs.hours, pdb_get_hours(pw), MAX_HOURS_LEN);
 	} else
 		memset(&usr->logon_hrs, 0xff, sizeof(usr->logon_hrs));
+
+	return NT_STATUS_OK;
 }
 
 /*******************************************************************
Index: source/rpc_server/srv_samr_nt.c
===================================================================
RCS file: /data/cvs/samba/source/rpc_server/srv_samr_nt.c,v
retrieving revision 1.98
diff -u -r1.98 srv_samr_nt.c
--- source/rpc_server/srv_samr_nt.c	2002/06/25 11:21:41	1.98
+++ source/rpc_server/srv_samr_nt.c	2002/06/26 03:24:33
@@ -126,19 +126,6 @@
  Ensure password info is never given out. Paranioa... JRA.
  ********************************************************************/
 
-static void samr_clear_passwd_fields( SAM_USER_INFO_21 *pass, int num_entries)
-{
-	int i;
-
-	if (!pass)
-		return;
-
-	for (i = 0; i < num_entries; i++) {
-		memset(&pass[i].lm_pwd, '\0', sizeof(pass[i].lm_pwd));
-		memset(&pass[i].nt_pwd, '\0', sizeof(pass[i].nt_pwd));
-	}
-}
-
 static void samr_clear_sam_passwd(SAM_ACCOUNT *sam_pass)
 {
 	
@@ -267,103 +254,6 @@
 
 
 /*******************************************************************
-  This next function should be replaced with something that
-  dynamically returns the correct user info..... JRA.
- ********************************************************************/
-
-static NTSTATUS get_sampwd_entries(SAM_USER_INFO_21 *pw_buf, int start_idx,
-                                int *total_entries, int *num_entries,
-                                int max_num_entries, uint16 acb_mask)
-{
-	SAM_ACCOUNT *pwd = NULL;
-	BOOL not_finished = True;
-	NTSTATUS nt_status;
-
-	(*num_entries) = 0;
-	(*total_entries) = 0;
-
-	if (pw_buf == NULL)
-		return NT_STATUS_NO_MEMORY;
-
-	if (!NT_STATUS_IS_OK(nt_status = pdb_init_sam(&pwd))) {
-		return nt_status;
-	}
-
-	if (!pdb_setsampwent(False)) {
-		DEBUG(0, ("get_sampwd_entries: Unable to open passdb.\n"));
-		pdb_free_sam(&pwd);
-		return NT_STATUS_ACCESS_DENIED;
-	}
-	
-	while (((not_finished = pdb_getsampwent(pwd)) != False) 
-	       && (*num_entries) < max_num_entries) 
-	{
-	        int user_name_len;
-		const char *user_name;
-
-	        if (start_idx > 0) {
-
-			pdb_free_sam(&pwd);
-			
-			if (!NT_STATUS_IS_OK(nt_status = pdb_init_sam(&pwd))) {
-				pdb_endsampwent();
-				return nt_status;
-			}
-
-			/* skip the requested number of entries.
-			   not very efficient, but hey...  */
-			start_idx--;
-			continue;
-		}
-		
-		user_name = pdb_get_username(pwd);
-
-		if (!user_name) {
-			DEBUG(2, ("account had NULL username!\n"));
-		} else if (!(acb_mask == 0 || (pdb_get_acct_ctrl(pwd) & acb_mask))) {
-			DEBUG(5,(" acb_mask %x rejects\n", acb_mask));
-		} else {
-			DEBUG(5,(" acb_mask %x accepts\n", acb_mask));
-			
-			user_name_len = strlen(user_name)+1;
-			init_unistr2(&pw_buf[(*num_entries)].uni_user_name, user_name, user_name_len);
-			init_uni_hdr(&pw_buf[(*num_entries)].hdr_user_name, user_name_len);
-			pw_buf[(*num_entries)].user_rid = pdb_get_user_rid(pwd);
-			memset((char *)pw_buf[(*num_entries)].nt_pwd, '\0', 16);
-			
-			/* Now check if the NT compatible password is available. */
-			if (pdb_get_nt_passwd(pwd))
-				memcpy( pw_buf[(*num_entries)].nt_pwd , pdb_get_nt_passwd(pwd), 16);
-			
-			pw_buf[(*num_entries)].acb_info = pdb_get_acct_ctrl(pwd);
-			
-			DEBUG(5, ("entry idx: %d user %s, rid 0x%x, acb %x",
-				  (*num_entries), pdb_get_username(pwd), pdb_get_user_rid(pwd), pdb_get_acct_ctrl(pwd) ));
-			
-			(*num_entries)++;
-		}
-
-		(*total_entries)++;
-		
-		pdb_free_sam(&pwd);
-
-		if (!NT_STATUS_IS_OK(nt_status = pdb_init_sam(&pwd))) {
-			pdb_endsampwent();
-			return nt_status;
-		}
-
-	}
-	
-	pdb_endsampwent();
-	pdb_free_sam(&pwd);
-
-	if (not_finished)
-		return STATUS_MORE_ENTRIES;
-	else
-		return NT_STATUS_OK;
-}
-
-/*******************************************************************
  _samr_close_hnd
  ********************************************************************/
 
@@ -526,69 +416,118 @@
 makes a SAM_ENTRY / UNISTR2* structure from a user list.
 ********************************************************************/
 
-static void make_user_sam_entry_list(TALLOC_CTX *ctx, SAM_ENTRY **sam_pp, UNISTR2 **uni_name_pp,
-                uint32 num_sam_entries, SAM_USER_INFO_21 *pass)
+static NTSTATUS make_user_sam_entry_list(TALLOC_CTX *ctx, SAM_ENTRY **sam_pp, UNISTR2 **uni_name_pp,
+					 uint32 num_entries, uint32 start_idx, DISP_USER_INFO *disp_user_info,
+					 DOM_SID *domain_sid)
 {
 	uint32 i;
 	SAM_ENTRY *sam;
 	UNISTR2 *uni_name;
-
+	SAM_ACCOUNT *pwd = NULL;
+	UNISTR2 uni_temp_name;
+	const char *temp_name;
+	const DOM_SID *user_sid;
+	uint32 user_rid;
+	fstring user_sid_string;
+	fstring domain_sid_string;
+	
 	*sam_pp = NULL;
 	*uni_name_pp = NULL;
 
-	if (num_sam_entries == 0)
-		return;
+	if (num_entries == 0)
+		return NT_STATUS_OK;
 
-	sam = (SAM_ENTRY *)talloc_zero(ctx, sizeof(SAM_ENTRY)*num_sam_entries);
+	sam = (SAM_ENTRY *)talloc_zero(ctx, sizeof(SAM_ENTRY)*num_entries);
 
-	uni_name = (UNISTR2 *)talloc_zero(ctx, sizeof(UNISTR2)*num_sam_entries);
+	uni_name = (UNISTR2 *)talloc_zero(ctx, sizeof(UNISTR2)*num_entries);
 
 	if (sam == NULL || uni_name == NULL) {
-		DEBUG(0, ("NULL pointers in SAMR_R_QUERY_DISPINFO\n"));
-		return;
+		DEBUG(0, ("make_user_sam_entry_list: talloc_zero failed!\n"));
+		return NT_STATUS_NO_MEMORY;
 	}
-
-	ZERO_STRUCTP(sam);
-	ZERO_STRUCTP(uni_name);
 
-	for (i = 0; i < num_sam_entries; i++) {
-		int len = pass[i].uni_user_name.uni_str_len;
+	for (i = 0; i < num_entries; i++) {
+		int len = uni_temp_name.uni_str_len;
+		
+		pwd = disp_user_info[i+start_idx].sam;
+		temp_name = pdb_get_username(pwd);
+		init_unistr2(&uni_temp_name, temp_name, strlen(temp_name)+1);
+		user_sid = pdb_get_user_sid(pwd);
+
+		if (!sid_peek_check_rid(domain_sid, user_sid, &user_rid)) {
+			DEBUG(0, ("make_user_sam_entry_list: User %s has SID %s, which conflicts with "
+				  "the domain sid %s.  Failing operation.\n", 
+				  temp_name, 
+				  sid_to_string(user_sid_string, user_sid),
+				  sid_to_string(domain_sid_string, domain_sid)));
+			return NT_STATUS_UNSUCCESSFUL;
+		}
 
-		init_sam_entry(&sam[i], len, pass[i].user_rid);
-		copy_unistr2(&uni_name[i], &pass[i].uni_user_name);
+		init_sam_entry(&sam[i], len, user_rid);
+		copy_unistr2(&uni_name[i], &uni_temp_name);
 	}
 
 	*sam_pp = sam;
 	*uni_name_pp = uni_name;
+	return NT_STATUS_OK;
 }
 
 /*******************************************************************
  samr_reply_enum_dom_users
  ********************************************************************/
 
-NTSTATUS _samr_enum_dom_users(pipes_struct *p, SAMR_Q_ENUM_DOM_USERS *q_u, SAMR_R_ENUM_DOM_USERS *r_u)
+NTSTATUS _samr_enum_dom_users(pipes_struct *p, SAMR_Q_ENUM_DOM_USERS *q_u, 
+			      SAMR_R_ENUM_DOM_USERS *r_u)
 {
-	SAM_USER_INFO_21 pass[MAX_SAM_ENTRIES];
-	int num_entries = 0;
-	int total_entries = 0;
+	struct samr_info *info = NULL;
+	uint32 struct_size=0x20; /* W2K always reply that, client doesn't care */
+	int num_account;
+	uint32 enum_context=q_u->start_idx;
+	uint32 max_size=q_u->max_size;
+	uint32 temp_size;
+	enum remote_arch_types ra_type = get_remote_arch();
+	int max_sam_entries = (ra_type == RA_WIN95) ? MAX_SAM_ENTRIES_W95 : MAX_SAM_ENTRIES_W2K;
+	uint32 max_entries = max_sam_entries;
+	DOM_SID domain_sid;
 	
 	r_u->status = NT_STATUS_OK;
 
 	/* find the policy handle.  open a policy on it. */
-	if (!find_policy_by_hnd(p, &q_u->pol, NULL))
+	if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
+		return NT_STATUS_INVALID_HANDLE;
+
+	if (!get_lsa_policy_samr_sid(p, &q_u->pol, &domain_sid))
 		return NT_STATUS_INVALID_HANDLE;
 
 	DEBUG(5,("_samr_enum_dom_users: %d\n", __LINE__));
 
 	become_root();
-	r_u->status = get_sampwd_entries(pass, q_u->start_idx, &total_entries, &num_entries,
-								MAX_SAM_ENTRIES, q_u->acb_mask);
+	r_u->status=load_sampwd_entries(info, q_u->acb_mask);
 	unbecome_root();
-
-	if (NT_STATUS_IS_ERR(r_u->status))
+	
+	if (!NT_STATUS_IS_OK(r_u->status))
 		return r_u->status;
+
+	num_account = info->disp_info.num_user_account;
 
-	samr_clear_passwd_fields(pass, num_entries);
+	if (enum_context > num_account) {
+		DEBUG(5, ("_samr_enum_dom_users: enumeration handle over total entries\n"));
+		return NT_STATUS_OK;
+	}
+
+	/* verify we won't overflow */
+	if (max_entries > num_account-enum_context) {
+		max_entries = num_account-enum_context;
+		DEBUG(5, ("_samr_enum_dom_users: only %d entries to return\n", max_entries));
+	}
+
+	/* calculate the size and limit on the number of entries we will return */
+	temp_size=max_entries*struct_size;
+	
+	if (temp_size>max_size) {
+		max_entries=MIN((max_size/struct_size),max_entries);;
+		DEBUG(5, ("_samr_enum_dom_users: buffer size limits to only %d entries\n", max_entries));
+	}
 
 	/* 
 	 * Note from JRA. total_entries is not being used here. Currently if there is a
@@ -602,10 +541,21 @@
 	 * the "max entries" parameter - but in the TNG code they're all currently set to the same
 	 * value (again I think this is wrong).
 	 */
+
+	r_u->status = make_user_sam_entry_list(p->mem_ctx, &r_u->sam, &r_u->uni_acct_name, 
+					       max_entries, enum_context, 
+					       info->disp_info.disp_user_info,
+					       &domain_sid);
+
+	if (!NT_STATUS_IS_OK(r_u->status))
+		return r_u->status;
+
+	if (enum_context+max_entries < num_account)
+		r_u->status = STATUS_MORE_ENTRIES;
 
-	make_user_sam_entry_list(p->mem_ctx, &r_u->sam, &r_u->uni_acct_name, num_entries, pass);
+	DEBUG(5, ("_samr_enum_dom_users: %d\n", __LINE__));
 
-	init_samr_r_enum_dom_users(r_u, q_u->start_idx + num_entries, num_entries);
+	init_samr_r_enum_dom_users(r_u, q_u->start_idx + max_entries, max_entries);
 
 	DEBUG(5,("_samr_enum_dom_users: %d\n", __LINE__));
 
@@ -891,7 +841,8 @@
 /*******************************************************************
  samr_reply_query_dispinfo
  ********************************************************************/
-NTSTATUS _samr_query_dispinfo(pipes_struct *p, SAMR_Q_QUERY_DISPINFO *q_u, SAMR_R_QUERY_DISPINFO *r_u)
+NTSTATUS _samr_query_dispinfo(pipes_struct *p, SAMR_Q_QUERY_DISPINFO *q_u, 
+			      SAMR_R_QUERY_DISPINFO *r_u)
 {
 	struct samr_info *info = NULL;
 	uint32 struct_size=0x20; /* W2K always reply that, client doesn't care */
@@ -906,10 +857,9 @@
 	NTSTATUS disp_ret;
 	uint32 num_account = 0;
 	enum remote_arch_types ra_type = get_remote_arch();
-	int max_sam_entries;
+	int max_sam_entries = (ra_type == RA_WIN95) ? MAX_SAM_ENTRIES_W95 : MAX_SAM_ENTRIES_W2K;
+	DOM_SID domain_sid;
 
-	max_sam_entries = (ra_type == RA_WIN95) ? MAX_SAM_ENTRIES_W95 : MAX_SAM_ENTRIES_W2K;
-
 	DEBUG(5, ("samr_reply_query_dispinfo: %d\n", __LINE__));
 	r_u->status = NT_STATUS_OK;
 
@@ -917,6 +867,9 @@
 	if (!find_policy_by_hnd(p, &q_u->domain_pol, (void **)&info))
 		return NT_STATUS_INVALID_HANDLE;
 
+	if (!get_lsa_policy_samr_sid(p, &q_u->domain_pol, &domain_sid))
+		return NT_STATUS_INVALID_HANDLE;
+
 	/*
 	 * calculate how many entries we will return.
 	 * based on 
@@ -1015,7 +968,8 @@
 			if (!(ctr->sam.info1 = (SAM_DISPINFO_1 *)talloc_zero(p->mem_ctx,max_entries*sizeof(SAM_DISPINFO_1))))
 				return NT_STATUS_NO_MEMORY;
 		}
-		disp_ret = init_sam_dispinfo_1(p->mem_ctx, ctr->sam.info1, max_entries, enum_context, info->disp_info.disp_user_info);
+		disp_ret = init_sam_dispinfo_1(p->mem_ctx, ctr->sam.info1, max_entries, enum_context, 
+					       info->disp_info.disp_user_info, &domain_sid);
 		if (!NT_STATUS_IS_OK(disp_ret))
 			return disp_ret;
 		break;
@@ -1024,7 +978,8 @@
 			if (!(ctr->sam.info2 = (SAM_DISPINFO_2 *)talloc_zero(p->mem_ctx,max_entries*sizeof(SAM_DISPINFO_2))))
 				return NT_STATUS_NO_MEMORY;
 		}
-		disp_ret = init_sam_dispinfo_2(p->mem_ctx, ctr->sam.info2, max_entries, enum_context, info->disp_info.disp_user_info);
+		disp_ret = init_sam_dispinfo_2(p->mem_ctx, ctr->sam.info2, max_entries, enum_context, 
+					       info->disp_info.disp_user_info, &domain_sid);
 		if (!NT_STATUS_IS_OK(disp_ret))
 			return disp_ret;
 		break;
@@ -1582,7 +1537,8 @@
  get_user_info_21
  *************************************************************************/
 
-static NTSTATUS get_user_info_21(TALLOC_CTX *mem_ctx, SAM_USER_INFO_21 *id21, DOM_SID *user_sid)
+static NTSTATUS get_user_info_21(TALLOC_CTX *mem_ctx, SAM_USER_INFO_21 *id21, 
+				 DOM_SID *user_sid, DOM_SID *domain_sid)
 {
 	SAM_ACCOUNT *sampass=NULL;
 	BOOL ret;
@@ -1607,7 +1563,7 @@
 	DEBUG(3,("User:[%s]\n",  pdb_get_username(sampass) ));
 
 	ZERO_STRUCTP(id21);
-	init_sam_user_info21A(id21, sampass);
+	nt_status = init_sam_user_info21A(id21, sampass, domain_sid);
 	
 	pdb_free_sam(&sampass);
 
@@ -1622,13 +1578,19 @@
 {
 	SAM_USERINFO_CTR *ctr;
 	struct samr_info *info = NULL;
-
+	DOM_SID domain_sid;
+	uint32 rid;
+	
 	r_u->status=NT_STATUS_OK;
 
 	/* search for the handle */
 	if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
 		return NT_STATUS_INVALID_HANDLE;
 
+	domain_sid = info->sid;
+
+	sid_split_rid(&domain_sid, &rid);
+
 	if (!sid_check_is_in_our_domain(&info->sid))
 		return NT_STATUS_OBJECT_TYPE_MISMATCH;
 
@@ -1700,7 +1662,8 @@
 		ctr->info.id21 = (SAM_USER_INFO_21 *)talloc_zero(p->mem_ctx,sizeof(SAM_USER_INFO_21));
 		if (ctr->info.id21 == NULL)
 			return NT_STATUS_NO_MEMORY;
-		if (!NT_STATUS_IS_OK(r_u->status = get_user_info_21(p->mem_ctx, ctr->info.id21, &info->sid)))
+		if (!NT_STATUS_IS_OK(r_u->status = get_user_info_21(p->mem_ctx, ctr->info.id21, 
+								    &info->sid, &domain_sid)))
 			return r_u->status;
 		break;
 
--- /dev/null	Fri Apr 12 00:25:15 2002
+++ source/passdb/pdb_compat.c	Tue Jun 25 00:22:03 2002
@@ -0,0 +1,104 @@
+/* 
+   Unix SMB/CIFS implementation.
+   SAM_ACCOUNT access routines
+   Copyright (C) Jeremy Allison 		1996-2001
+   Copyright (C) Luke Kenneth Casson Leighton 	1996-1998
+   Copyright (C) Gerald (Jerry) Carter		2000-2001
+   Copyright (C) Andrew Bartlett		2001-2002
+   Copyright (C) Stefan (metze) Metzmacher	2002
+      
+   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.
+*/
+
+#include "includes.h"
+
+#undef DBGC_CLASS
+#define DBGC_CLASS DBGC_PASSDB
+
+uint32 pdb_get_user_rid (const SAM_ACCOUNT *sampass)
+{
+	uint32 u_rid;
+
+	if (sampass)
+		if (sid_peek_check_rid(get_global_sam_sid(), pdb_get_user_sid(sampass),&u_rid))
+			return u_rid;
+	
+	return (0);
+}
+
+uint32 pdb_get_group_rid (const SAM_ACCOUNT *sampass)
+{
+	uint32 g_rid;
+
+	if (sampass)
+		if (sid_peek_check_rid(get_global_sam_sid(), pdb_get_group_sid(sampass),&g_rid))
+			return g_rid;
+	return (0);
+}
+
+BOOL pdb_set_user_sid_from_rid (SAM_ACCOUNT *sampass, uint32 rid)
+{
+	DOM_SID u_sid;
+	const DOM_SID *global_sam_sid;
+	
+	if (!sampass)
+		return False;
+
+	if (!(global_sam_sid = get_global_sam_sid())) {
+		DEBUG(1, ("pdb_set_user_sid_from_rid: Could not read global sam sid!\n"));
+		return False;
+	}
+
+	sid_copy(&u_sid, global_sam_sid);
+
+	if (!sid_append_rid(&u_sid, rid))
+		return False;
+
+	if (!pdb_set_user_sid(sampass, &u_sid))
+		return False;
+
+	DEBUG(10, ("pdb_set_user_sid_from_rid:\n\tsetting user sid %s from rid %d\n", 
+		    sid_string_static(&u_sid),rid));
+
+	return True;
+}
+
+BOOL pdb_set_group_sid_from_rid (SAM_ACCOUNT *sampass, uint32 grid)
+{
+	DOM_SID g_sid;
+	const DOM_SID *global_sam_sid;
+
+	if (!sampass)
+		return False;
+	
+	if (!(global_sam_sid = get_global_sam_sid())) {
+		DEBUG(1, ("pdb_set_user_sid_from_rid: Could not read global sam sid!\n"));
+		return False;
+	}
+
+	sid_copy(&g_sid, global_sam_sid);
+	
+	if (!sid_append_rid(&g_sid, grid))
+		return False;
+
+	if (!pdb_set_group_sid(sampass, &g_sid))
+		return False;
+
+	DEBUG(10, ("pdb_set_group_sid_from_rid:\n\tsetting group sid %s from rid %d\n", 
+		    sid_string_static(&g_sid), grid));
+
+	return True;
+}
+
--- /dev/null	Fri Apr 12 00:25:15 2002
+++ source/rpc_server/srv_samr_util.c	Mon Jun 24 19:47:49 2002
@@ -0,0 +1,143 @@
+/* 
+   Unix SMB/CIFS implementation.
+   SAMR Pipe utility functions.
+   Copyright (C) Jeremy Allison 		1996-2001
+   Copyright (C) Luke Kenneth Casson Leighton 	1996-1998
+   Copyright (C) Gerald (Jerry) Carter		2000-2001
+   Copyright (C) Andrew Bartlett		2001-2002
+      
+   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.
+*/
+
+#include "includes.h"
+
+#undef DBGC_CLASS
+#define DBGC_CLASS DBGC_RPC_SRV
+
+/*************************************************************
+ Copies a SAM_USER_INFO_23 to a SAM_ACCOUNT
+ **************************************************************/
+
+void copy_id23_to_sam_passwd(SAM_ACCOUNT *to, SAM_USER_INFO_23 *from)
+{
+
+	if (from == NULL || to == NULL) 
+		return;
+
+	pdb_set_logon_time(to,nt_time_to_unix(&from->logon_time), True);
+	pdb_set_logoff_time(to,nt_time_to_unix(&from->logoff_time), True);
+	pdb_set_kickoff_time(to, nt_time_to_unix(&from->kickoff_time), True);
+	pdb_set_pass_can_change_time(to, nt_time_to_unix(&from->pass_can_change_time), True);
+	pdb_set_pass_must_change_time(to, nt_time_to_unix(&from->pass_must_change_time), True);
+
+	pdb_set_pass_last_set_time(to, nt_time_to_unix(&from->pass_last_set_time));
+
+	if (from->uni_user_name.buffer)
+		pdb_set_username(to      , pdb_unistr2_convert(&from->uni_user_name   ));
+	if (from->uni_full_name.buffer)
+		pdb_set_fullname(to      , pdb_unistr2_convert(&from->uni_full_name   ));
+	if (from->uni_home_dir.buffer)
+		pdb_set_homedir(to       , pdb_unistr2_convert(&from->uni_home_dir    ), True);
+	if (from->uni_dir_drive.buffer)
+		pdb_set_dir_drive(to     , pdb_unistr2_convert(&from->uni_dir_drive   ), True);
+	if (from->uni_logon_script.buffer)
+		pdb_set_logon_script(to  , pdb_unistr2_convert(&from->uni_logon_script), True);
+	if (from->uni_profile_path.buffer)
+		pdb_set_profile_path(to  , pdb_unistr2_convert(&from->uni_profile_path), True);
+	if (from->uni_acct_desc.buffer)
+		pdb_set_acct_desc(to     , pdb_unistr2_convert(&from->uni_acct_desc   ));
+	if (from->uni_workstations.buffer)
+		pdb_set_workstations(to  , pdb_unistr2_convert(&from->uni_workstations));
+	if (from->uni_unknown_str.buffer)
+		pdb_set_unknown_str(to   , pdb_unistr2_convert(&from->uni_unknown_str ));
+	if (from->uni_munged_dial.buffer)
+		pdb_set_munged_dial(to   , pdb_unistr2_convert(&from->uni_munged_dial ));
+
+	if (from->user_rid)
+		pdb_set_user_sid_from_rid(to, from->user_rid);
+	if (from->group_rid)
+		pdb_set_group_sid_from_rid(to, from->group_rid);
+
+	pdb_set_acct_ctrl(to, from->acb_info);
+	pdb_set_unknown_3(to, from->unknown_3);
+
+	pdb_set_logon_divs(to, from->logon_divs);
+	pdb_set_hours_len(to, from->logon_hrs.len);
+	pdb_set_hours(to, from->logon_hrs.hours);
+
+	pdb_set_unknown_5(to, from->unknown_5);
+	pdb_set_unknown_6(to, from->unknown_6);
+}
+
+
+/*************************************************************
+ Copies a sam passwd.
+ **************************************************************/
+
+void copy_id21_to_sam_passwd(SAM_ACCOUNT *to, SAM_USER_INFO_21 *from)
+{
+	if (from == NULL || to == NULL) 
+		return;
+
+	pdb_set_logon_time(to,nt_time_to_unix(&from->logon_time), True);
+	pdb_set_logoff_time(to,nt_time_to_unix(&from->logoff_time), True);
+	pdb_set_kickoff_time(to, nt_time_to_unix(&from->kickoff_time), True);
+	pdb_set_pass_can_change_time(to, nt_time_to_unix(&from->pass_can_change_time), True);
+	pdb_set_pass_must_change_time(to, nt_time_to_unix(&from->pass_must_change_time), True);
+
+	pdb_set_pass_last_set_time(to, nt_time_to_unix(&from->pass_last_set_time));
+
+	if (from->uni_user_name.buffer)
+		pdb_set_username(to      , pdb_unistr2_convert(&from->uni_user_name   ));
+	if (from->uni_full_name.buffer)
+		pdb_set_fullname(to      , pdb_unistr2_convert(&from->uni_full_name   ));
+	if (from->uni_home_dir.buffer)
+		pdb_set_homedir(to       , pdb_unistr2_convert(&from->uni_home_dir    ), True);
+	if (from->uni_dir_drive.buffer)
+		pdb_set_dir_drive(to     , pdb_unistr2_convert(&from->uni_dir_drive   ), True);
+	if (from->uni_logon_script.buffer)
+		pdb_set_logon_script(to  , pdb_unistr2_convert(&from->uni_logon_script), True);
+	if (from->uni_profile_path.buffer)
+		pdb_set_profile_path(to  , pdb_unistr2_convert(&from->uni_profile_path), True);
+	if (from->uni_acct_desc.buffer)
+		pdb_set_acct_desc(to     , pdb_unistr2_convert(&from->uni_acct_desc   ));
+	if (from->uni_workstations.buffer)
+		pdb_set_workstations(to  , pdb_unistr2_convert(&from->uni_workstations));
+	if (from->uni_unknown_str.buffer)
+		pdb_set_unknown_str(to   , pdb_unistr2_convert(&from->uni_unknown_str ));
+	if (from->uni_munged_dial.buffer)
+		pdb_set_munged_dial(to   , pdb_unistr2_convert(&from->uni_munged_dial ));
+
+	if (from->user_rid)
+		pdb_set_user_sid_from_rid(to, from->user_rid);
+	if (from->group_rid)
+		pdb_set_group_sid_from_rid(to, from->group_rid);
+
+	/* FIXME!!  Do we need to copy the passwords here as well?
+	   I don't know.  Need to figure this out   --jerry */
+
+	/* Passwords dealt with in caller --abartlet */
+
+	pdb_set_acct_ctrl(to, from->acb_info);
+	pdb_set_unknown_3(to, from->unknown_3);
+
+	pdb_set_logon_divs(to, from->logon_divs);
+	pdb_set_hours_len(to, from->logon_hrs.len);
+	pdb_set_hours(to, from->logon_hrs.hours);
+
+	pdb_set_unknown_5(to, from->unknown_5);
+	pdb_set_unknown_6(to, from->unknown_6);
+}
+


More information about the samba-technical mailing list