[PATCH] Use idmap in pdb_set_sam_sids()

Luke Howard lukeh at PADL.COM
Thu Aug 19 09:16:04 GMT 2004


>From my side this looks good. And it fixes a long-standing bug I've had, but
>that did not have enough pressure...

Volker pointed out that there is a potential infinite recursion in my
initial patch. As I understand it, the loop is as follows:

	uid_to_sid -> local_uid_to_sid -> smbpasswd_getsampwnam ->
	build_sam_account -> pdb_fill_sam_pw -> pdb_set_sam_sids ->
	uid_to_sid -> ...

The attached patch attempts to fix this issue by extending the API to
indicate whether non-algorithmic UID/GID mapping is to be used. Hence
smbpasswd_getsampwnam() can avoid calling uid_to_sid(), whilst the
authentication subsystem can still have it called implicitly.

Comments appreciated. Obviously the previous patch should be backed
out (although it does appear to work fine for me).

regards,

-- Luke

-------------- next part --------------
Index: auth/auth_util.c
===================================================================
RCS file: /home/project/cvs/samba/source/auth/auth_util.c,v
retrieving revision 1.1.1.7
diff -u -r1.1.1.7 auth_util.c
--- auth/auth_util.c	16 Aug 2004 01:26:02 -0000	1.1.1.7
+++ auth/auth_util.c	19 Aug 2004 08:47:33 -0000
@@ -107,7 +107,7 @@
 		if (!pass) 
 			return NT_STATUS_NO_SUCH_USER;
 
-		if (!NT_STATUS_IS_OK(nt_status = pdb_fill_sam_pw(*account, pass))) {
+		if (!NT_STATUS_IS_OK(nt_status = pdb_fill_sam_pw(*account, pass, True))) {
 			return nt_status;
 		}
 	}
@@ -857,7 +857,7 @@
 {
 	NTSTATUS nt_status;
 	SAM_ACCOUNT *sampass = NULL;
-	if (!NT_STATUS_IS_OK(nt_status = pdb_init_sam_pw(&sampass, pwd))) {		
+	if (!NT_STATUS_IS_OK(nt_status = pdb_init_sam_pw(&sampass, pwd, True))) {
 		return nt_status;
 	}
 	if (!NT_STATUS_IS_OK(nt_status = make_server_info(server_info))) {
@@ -959,7 +959,7 @@
 	DEBUG(5,("fill_sam_account: located username was [%s]\n",
 		*found_username));
 
-	return pdb_init_sam_pw(sam_account, passwd);
+	return pdb_init_sam_pw(sam_account, passwd, True);
 }
 
 /****************************************************************************
Index: passdb/passdb.c
===================================================================
RCS file: /home/project/cvs/samba/source/passdb/passdb.c,v
retrieving revision 1.1.1.7
diff -u -r1.1.1.7 passdb.c
--- passdb/passdb.c	16 Aug 2004 01:26:09 -0000	1.1.1.7
+++ passdb/passdb.c	19 Aug 2004 08:47:34 -0000
@@ -182,15 +182,20 @@
  * users, messing with SIDs is not good.
  *
  * account_data must be provided initialized, pwd may be null.
+ *
+ * if idmap is TRUE, then UIDs/GIDs will be mapped to SIDs; otherwise
+ * the algorithmic mapping is used
  * 									SSS
  ***************************************************************************/
 
-static NTSTATUS pdb_set_sam_sids(SAM_ACCOUNT *account_data, const struct passwd *pwd)
+static NTSTATUS pdb_set_sam_sids(SAM_ACCOUNT *account_data, const struct passwd *pwd, BOOL idmap)
 {
 	const char *guest_account = lp_guestaccount();
 	GROUP_MAP map;
 	BOOL ret;
-	
+	DOM_SID user_sid;
+	DOM_SID group_sid;
+
 	if (!account_data || !pwd) {
 		return NT_STATUS_INVALID_PARAMETER;
 	}
@@ -213,7 +218,12 @@
 		}
 	}
 
-	if (!pdb_set_user_sid_from_rid(account_data, fallback_pdb_uid_to_user_rid(pwd->pw_uid), PDB_SET)) {
+	if (idmap && NT_STATUS_IS_OK(uid_to_sid(&user_sid, pwd->pw_uid))) {
+		if (!pdb_set_user_sid(account_data, &user_sid, PDB_SET)) {
+			DEBUG(0,("Can't set User SID from mapped UID\n"));
+			return NT_STATUS_INVALID_PARAMETER;
+		}
+	} else if (!pdb_set_user_sid_from_rid(account_data, fallback_pdb_uid_to_user_rid(pwd->pw_uid), PDB_SET)) {
 		DEBUG(0,("Can't set User SID from RID!\n"));
 		return NT_STATUS_INVALID_PARAMETER;
 	}
@@ -230,7 +240,12 @@
 		}
 	} 
 	else {
-		if (!pdb_set_group_sid_from_rid(account_data, pdb_gid_to_group_rid(pwd->pw_gid), PDB_SET)) {
+		if (idmap && NT_STATUS_IS_OK(gid_to_sid(&group_sid, pwd->pw_gid))) {
+			if (!pdb_set_group_sid(account_data, &group_sid, PDB_SET)) {
+				DEBUG(0,("Can't set Group SID from mapped GID\n"));
+				return NT_STATUS_INVALID_PARAMETER;
+			}
+		} else if (!pdb_set_group_sid_from_rid(account_data, pdb_gid_to_group_rid(pwd->pw_gid), PDB_SET)) {
 			DEBUG(0,("Can't set Group SID\n"));
 			return NT_STATUS_INVALID_PARAMETER;
 		}
@@ -241,9 +256,12 @@
 
 /*************************************************************
  Initialises a struct sam_passwd with sane values.
+
+ The idmap parameter determines whether non-algorithmic (eg.
+ winbindd) mapping is done of the user's primary UID/GID.
  ************************************************************/
 
-NTSTATUS pdb_fill_sam_pw(SAM_ACCOUNT *sam_account, const struct passwd *pwd)
+NTSTATUS pdb_fill_sam_pw(SAM_ACCOUNT *sam_account, const struct passwd *pwd, BOOL idmap)
 {
 	NTSTATUS ret;
 
@@ -270,7 +288,7 @@
 	   -- abartlet 11-May-02
 	*/
 
-	ret = pdb_set_sam_sids(sam_account, pwd);
+	ret = pdb_set_sam_sids(sam_account, pwd, idmap);
 	if (!NT_STATUS_IS_OK(ret)) return ret;
 
 	/* check if this is a user account or a machine account */
@@ -321,7 +339,7 @@
  Initialises a struct sam_passwd with sane values.
  ************************************************************/
 
-NTSTATUS pdb_init_sam_pw(SAM_ACCOUNT **new_sam_acct, const struct passwd *pwd)
+NTSTATUS pdb_init_sam_pw(SAM_ACCOUNT **new_sam_acct, const struct passwd *pwd, BOOL idmap)
 {
 	NTSTATUS nt_status;
 
@@ -335,7 +353,7 @@
 		return nt_status;
 	}
 
-	if (!NT_STATUS_IS_OK(nt_status = pdb_fill_sam_pw(*new_sam_acct, pwd))) {
+	if (!NT_STATUS_IS_OK(nt_status = pdb_fill_sam_pw(*new_sam_acct, pwd, idmap))) {
 		pdb_free_sam(new_sam_acct);
 		new_sam_acct = NULL;
 		return nt_status;
@@ -362,7 +380,7 @@
 	if (!pwd) 
 		return NT_STATUS_NO_SUCH_USER;
 	
-	if (!NT_STATUS_IS_OK(nt_status = pdb_init_sam_pw(new_sam_acct, pwd))) {
+	if (!NT_STATUS_IS_OK(nt_status = pdb_init_sam_pw(new_sam_acct, pwd, True))) {
 		*new_sam_acct = NULL;
 		return nt_status;
 	}
Index: passdb/pdb_smbpasswd.c
===================================================================
RCS file: /home/project/cvs/samba/source/passdb/pdb_smbpasswd.c,v
retrieving revision 1.1.1.6
diff -u -r1.1.1.6 pdb_smbpasswd.c
--- passdb/pdb_smbpasswd.c	7 Jan 2004 06:37:19 -0000	1.1.1.6
+++ passdb/pdb_smbpasswd.c	19 Aug 2004 08:47:34 -0000
@@ -1184,7 +1184,7 @@
 			return False;
 	}
 	
-	if (!NT_STATUS_IS_OK(pdb_fill_sam_pw(sam_pass, pwfile)))
+	if (!NT_STATUS_IS_OK(pdb_fill_sam_pw(sam_pass, pwfile, False)))
 		return False;
 		
 	passwd_free(&pwfile);
Index: utils/pdbedit.c
===================================================================
RCS file: /home/project/cvs/samba/source/utils/pdbedit.c,v
retrieving revision 1.1.1.8
diff -u -r1.1.1.8 pdbedit.c
--- utils/pdbedit.c	16 Aug 2004 01:26:05 -0000	1.1.1.8
+++ utils/pdbedit.c	19 Aug 2004 08:47:36 -0000
@@ -511,7 +511,7 @@
 	fstrcat(machineaccount, "$");
 
 	if ((pwd = getpwnam_alloc(machineaccount))) {
-		if (!NT_STATUS_IS_OK(pdb_init_sam_pw( &sam_pwent, pwd))) {
+		if (!NT_STATUS_IS_OK(pdb_init_sam_pw( &sam_pwent, pwd, False))) {
 			fprintf(stderr, "Could not init sam from pw\n");
 			passwd_free(&pwd);
 			return -1;


More information about the samba-technical mailing list