HEAD pdb_ldap
Volker Lendecke
Volker.Lendecke at SerNet.DE
Thu Mar 20 23:03:37 GMT 2003
Hi!
The attached patch changes some semantics in pdb_get_set.
I had the problem that I could not join a HEAD PDC with NT4. HEAD
tried to do illegal operations with the LDAP account, for example it
tried to set "displayName" to "", which is not allowed. I found we
have to track what attributes exist in LDAP to make the appropriate
change.
See the function make_ldap_mod for the core functionality.
To enable that, the semantics of IS_SAM_SET changed to: Did this exist
in LDAP? and IS_SAM_CHANGED means: Do we have to set it?
Not really tested what this semantic change breaks, but with that
patch I can now join HEAD with ldapsam again.
Comments?
BTW, this also does away with the 'cn' and 'displayName'
co-treatment. This is simply not possible.
Volker
Not signed, gpg would destroy the diff ;-)
Index: include/smb.h
===================================================================
RCS file: /space/vl/cvstree/samba/source/include/smb.h,v
retrieving revision 1.479
diff -u -r1.479 smb.h
--- include/smb.h 20 Mar 2003 00:32:44 -0000 1.479
+++ include/smb.h 20 Mar 2003 22:53:35 -0000
@@ -628,8 +628,6 @@
(( pdb_get_init_flags(x, PDB_UID) != PDB_DEFAULT ) \
&& ( pdb_get_init_flags(x,PDB_GID) != PDB_DEFAULT ))
-#define IS_SAM_SET(x, flag) (pdb_get_init_flags(x, flag) == PDB_SET)
-#define IS_SAM_CHANGED(x, flag) (pdb_get_init_flags(x, flag) == PDB_CHANGED)
#define IS_SAM_DEFAULT(x, flag) (pdb_get_init_flags(x, flag) == PDB_DEFAULT)
typedef struct sam_passwd
Index: passdb/passdb.c
===================================================================
RCS file: /space/vl/cvstree/samba/source/passdb/passdb.c,v
retrieving revision 1.187
diff -u -r1.187 passdb.c
--- passdb/passdb.c 22 Feb 2003 12:17:02 -0000 1.187
+++ passdb/passdb.c 20 Mar 2003 22:54:10 -0000
@@ -863,7 +863,8 @@
if (pdb_getsampwsid(sam_user, psid)) {
- if (!IS_SAM_SET(sam_user,PDB_UID)&&!IS_SAM_CHANGED(sam_user,PDB_UID)) {
+ if (!pdb_is_sam_set(sam_user,PDB_UID)&&
+ !pdb_is_sam_changed(sam_user,PDB_UID)) {
pdb_free_sam(&sam_user);
return False;
}
Index: passdb/pdb_get_set.c
===================================================================
RCS file: /space/vl/cvstree/samba/source/passdb/pdb_get_set.c,v
retrieving revision 1.23
diff -u -r1.23 pdb_get_set.c
--- passdb/pdb_get_set.c 20 Mar 2003 12:50:29 -0000 1.23
+++ passdb/pdb_get_set.c 20 Mar 2003 22:55:12 -0000
@@ -202,6 +202,22 @@
return ret;
}
+BOOL pdb_is_sam_set(const SAM_ACCOUNT *sampass, enum pdb_elements element)
+{
+ if (!sampass || !sampass->private.set_flags)
+ return False;
+
+ return bitmap_query(sampass->private.set_flags, element);
+}
+
+BOOL pdb_is_sam_changed(const SAM_ACCOUNT *sampass, enum pdb_elements element)
+{
+ if (!sampass || !sampass->private.change_flags)
+ return False;
+
+ return bitmap_query(sampass->private.change_flags, element);
+}
+
uid_t pdb_get_uid (const SAM_ACCOUNT *sampass)
{
if (sampass)
@@ -475,17 +491,9 @@
DEBUG(0,("Can't set flag: %d in change_flags.\n",element));
return False;
}
- if (!bitmap_set(sampass->private.set_flags, element)) {
- DEBUG(0,("Can't set flag: %d in set_flags.\n",element));
- return False;
- }
DEBUG(11, ("element %d -> now CHANGED\n", element));
break;
case PDB_SET:
- if (!bitmap_clear(sampass->private.change_flags, element)) {
- DEBUG(0,("Can't set flag: %d in change_flags.\n",element));
- return False;
- }
if (!bitmap_set(sampass->private.set_flags, element)) {
DEBUG(0,("Can't set flag: %d in set_flags.\n",element));
return False;
Index: passdb/pdb_ldap.c
===================================================================
RCS file: /space/vl/cvstree/samba/source/passdb/pdb_ldap.c,v
retrieving revision 1.88
diff -u -r1.88 pdb_ldap.c
--- passdb/pdb_ldap.c 20 Mar 2003 13:21:23 -0000 1.88
+++ passdb/pdb_ldap.c 20 Mar 2003 22:50:33 -0000
@@ -1158,12 +1158,8 @@
* that fits your needs; using cn then displayName rather than 'userFullName'
*/
- if (!get_single_attribute(ldap_state->ldap_struct, entry, "cn", fullname)) {
- if (!get_single_attribute(ldap_state->ldap_struct, entry, "displayName", fullname)) {
- /* leave as default */
- } else {
- pdb_set_fullname(sampass, fullname, PDB_SET);
- }
+ if (!get_single_attribute(ldap_state->ldap_struct, entry, "displayName", fullname)) {
+ /* leave as default */
} else {
pdb_set_fullname(sampass, fullname, PDB_SET);
}
@@ -1275,7 +1271,27 @@
if (pdb_add) {
return (!IS_SAM_DEFAULT(sampass, element));
} else {
- return IS_SAM_CHANGED(sampass, element);
+ return pdb_is_sam_changed(sampass, element);
+ }
+}
+
+static void make_ldap_mod(LDAPMod ***mods, const SAM_ACCOUNT *sampass,
+ enum pdb_elements element,
+ const char *attrib, const char *newval)
+{
+ if (!pdb_is_sam_changed(sampass, element))
+ return;
+
+ if (pdb_is_sam_set(sampass, element)) {
+ if (strlen(newval) > 0) {
+ make_a_mod(mods, LDAP_MOD_REPLACE, attrib, newval);
+ } else {
+ make_a_mod(mods, LDAP_MOD_DELETE, attrib, NULL);
+ }
+ } else {
+ if (strlen(newval) > 0) {
+ make_a_mod(mods, LDAP_MOD_ADD, attrib, newval);
+ }
}
}
@@ -1349,66 +1365,61 @@
return False;
}
+ make_ldap_mod(mods, sampass,
+ PDB_FULLNAME, "displayName",
+ pdb_get_fullname(sampass));
+
+ make_ldap_mod(mods, sampass,
+ PDB_ACCTDESC, "description",
+ pdb_get_acct_desc(sampass));
+
+ make_ldap_mod(mods, sampass,
+ PDB_WORKSTATIONS, "userWorkstations",
+ pdb_get_workstations(sampass));
+
+ make_ldap_mod(mods, sampass,
+ PDB_SMBHOME, "smbHome",
+ pdb_get_homedir(sampass));
+
+ make_ldap_mod(mods, sampass,
+ PDB_DRIVE, "homeDrive",
+ pdb_get_dir_drive(sampass));
+
+ make_ldap_mod(mods, sampass,
+ PDB_LOGONSCRIPT, "scriptPath",
+ pdb_get_logon_script(sampass));
+
+ make_ldap_mod(mods, sampass,
+ PDB_PROFILE, "profilePath",
+ pdb_get_profile_path(sampass));
+
+ slprintf(temp, sizeof(temp)-1, "%li", pdb_get_logon_time(sampass));
+ make_ldap_mod(mods, sampass,
+ PDB_LOGONTIME, "logonTime",
+ temp);
+
+ slprintf(temp, sizeof(temp)-1, "%li", pdb_get_logoff_time(sampass));
+ make_ldap_mod(mods, sampass,
+ PDB_LOGOFFTIME, "logoffTime",
+ temp);
- /* displayName, cn, and gecos should all be the same
- * most easily accomplished by giving them the same OID
- * gecos isn't set here b/c it should be handled by the
- * add-user script
- */
- if (need_ldap_mod(pdb_add, sampass, PDB_FULLNAME)) {
- make_a_mod(mods, ldap_op, "displayName", pdb_get_fullname(sampass));
- make_a_mod(mods, ldap_op, "cn", pdb_get_fullname(sampass));
- }
- if (need_ldap_mod(pdb_add, sampass, PDB_ACCTDESC)) {
- make_a_mod(mods, ldap_op, "description", pdb_get_acct_desc(sampass));
- }
- if (need_ldap_mod(pdb_add, sampass, PDB_WORKSTATIONS)) {
- make_a_mod(mods, ldap_op, "userWorkstations", pdb_get_workstations(sampass));
- }
- /*
- * Only updates fields which have been set (not defaults from smb.conf)
- */
-
- if (need_ldap_mod(pdb_add, sampass, PDB_SMBHOME)) {
- make_a_mod(mods, ldap_op, "smbHome", pdb_get_homedir(sampass));
- }
-
- if (need_ldap_mod(pdb_add, sampass, PDB_DRIVE)) {
- make_a_mod(mods, ldap_op, "homeDrive", pdb_get_dir_drive(sampass));
- }
-
- if (need_ldap_mod(pdb_add, sampass, PDB_LOGONSCRIPT)) {
- make_a_mod(mods, ldap_op, "scriptPath", pdb_get_logon_script(sampass));
- }
- if (need_ldap_mod(pdb_add, sampass, PDB_PROFILE))
- make_a_mod(mods, ldap_op, "profilePath", pdb_get_profile_path(sampass));
-
- if (need_ldap_mod(pdb_add, sampass, PDB_LOGONTIME)) {
- slprintf(temp, sizeof(temp) - 1, "%li", pdb_get_logon_time(sampass));
- make_a_mod(mods, ldap_op, "logonTime", temp);
- }
-
- if (need_ldap_mod(pdb_add, sampass, PDB_LOGOFFTIME)) {
- slprintf(temp, sizeof(temp) - 1, "%li", pdb_get_logoff_time(sampass));
- make_a_mod(mods, ldap_op, "logoffTime", temp);
- }
-
- if (need_ldap_mod(pdb_add, sampass, PDB_KICKOFFTIME)) {
- slprintf (temp, sizeof (temp) - 1, "%li", pdb_get_kickoff_time(sampass));
- make_a_mod(mods, ldap_op, "kickoffTime", temp);
- }
-
-
- if (need_ldap_mod(pdb_add, sampass, PDB_CANCHANGETIME)) {
- slprintf (temp, sizeof (temp) - 1, "%li", pdb_get_pass_can_change_time(sampass));
- make_a_mod(mods, ldap_op, "pwdCanChange", temp);
- }
-
- if (need_ldap_mod(pdb_add, sampass, PDB_MUSTCHANGETIME)) {
- slprintf (temp, sizeof (temp) - 1, "%li", pdb_get_pass_must_change_time(sampass));
- make_a_mod(mods, ldap_op, "pwdMustChange", temp);
- }
+ slprintf (temp, sizeof (temp)-1, "%li", pdb_get_kickoff_time(sampass));
+ make_ldap_mod(mods, sampass,
+ PDB_KICKOFFTIME, "kickoffTime",
+ temp);
+
+ slprintf (temp, sizeof (temp)-1, "%li",
+ pdb_get_pass_can_change_time(sampass));
+ make_ldap_mod(mods, sampass,
+ PDB_CANCHANGETIME, "pwdCanChange",
+ temp);
+
+ slprintf (temp, sizeof (temp)-1, "%li",
+ pdb_get_pass_must_change_time(sampass));
+ make_ldap_mod(mods, sampass,
+ PDB_MUSTCHANGETIME, "pwdMustChange",
+ temp);
if ((pdb_get_acct_ctrl(sampass)&(ACB_WSTRUST|ACB_SVRTRUST|ACB_DOMTRUST))||
(lp_ldap_passwd_sync()!=LDAP_PASSWD_SYNC_ONLY)) {
More information about the samba-technical
mailing list