Prevent winbind idmap corruption
Michael Steffens
michael_steffens at hp.com
Thu Dec 19 12:38:01 GMT 2002
Ooops, bug in patch: Duplicate deletion of mapping on
rollback. Corrected version is attached. Sorry!
Michael
-------------- next part --------------
Index: nsswitch/winbindd_idmap.c
===================================================================
RCS file: /cvsroot/samba/source/nsswitch/winbindd_idmap.c,v
retrieving revision 1.3.4.13
diff -u -r1.3.4.13 winbindd_idmap.c
--- nsswitch/winbindd_idmap.c 27 Apr 2002 03:04:08 -0000 1.3.4.13
+++ nsswitch/winbindd_idmap.c 19 Dec 2002 12:32:25 -0000
@@ -44,6 +44,8 @@
if ((hwm = tdb_fetch_int32(idmap_tdb,
isgroup ? HWM_GROUP : HWM_USER)) == -1) {
+ DEBUG(0, ("Failed to fetch %s : %s\n", isgroup ? HWM_GROUP : HWM_USER,
+ tdb_errorstr(idmap_tdb)));
return False;
}
@@ -63,7 +65,45 @@
/* Store new high water mark */
- tdb_store_int32(idmap_tdb, isgroup ? HWM_GROUP : HWM_USER, hwm);
+ if (tdb_store_int32(idmap_tdb, isgroup ? HWM_GROUP : HWM_USER, hwm)) {
+ DEBUG(0, ("Failed to store %s %d : %s\n", isgroup ? HWM_GROUP : HWM_USER,
+ hwm, tdb_errorstr(idmap_tdb)));
+ return False;
+ }
+
+ return True;
+}
+
+/* Deallocate either a user or group id, used for failure rollback */
+
+static BOOL deallocate_id(uid_t id, BOOL isgroup)
+{
+ int hwm;
+
+ /* Get current high water mark */
+
+ if ((hwm = tdb_fetch_int32(idmap_tdb,
+ isgroup ? HWM_GROUP : HWM_USER)) == -1) {
+ DEBUG(0, ("Failed to fetch %s : %s\n", isgroup ? HWM_GROUP : HWM_USER,
+ tdb_errorstr(idmap_tdb)));
+ return False;
+ }
+
+ if (hwm != id + 1) {
+ /* Should actually never happen, internal redundancy... */
+ DEBUG(0, ("winbind %s mismatch on deallocation!\n", isgroup ? HWM_GROUP : HWM_USER));
+ return False;
+ }
+
+ hwm--;
+
+ /* Store new high water mark */
+
+ if (tdb_store_int32(idmap_tdb, isgroup ? HWM_GROUP : HWM_USER, hwm)) {
+ DEBUG(0, ("Failed to store %s %d : %s\n", isgroup ? HWM_GROUP : HWM_USER,
+ hwm, tdb_errorstr(idmap_tdb)));
+ return False;
+ }
return True;
}
@@ -109,16 +149,36 @@
fstring keystr2;
/* Store new id */
-
+
slprintf(keystr2, sizeof(keystr2), "%s %d", isgroup ? "GID" : "UID", *id);
data.dptr = keystr2;
data.dsize = strlen(keystr2) + 1;
- tdb_store(idmap_tdb, key, data, TDB_REPLACE);
- tdb_store(idmap_tdb, data, key, TDB_REPLACE);
+ /* If any of the following actions fails try to
+ revert modifications successfully made so far. */
result = True;
+
+ if (result && tdb_store(idmap_tdb, key, data, TDB_REPLACE)) {
+ DEBUG(0, ("Failed to store id mapping %s:%s : %s\n",
+ key.dptr, data.dptr, tdb_errorstr(idmap_tdb)));
+
+ if (!deallocate_id(*id, isgroup))
+ DEBUG(0, ("Failed to rollback id mapping\n"));
+
+ result = False;
+ }
+
+ if (result && tdb_store(idmap_tdb, data, key, TDB_REPLACE)) {
+ DEBUG(0, ("Failed to store reverse id mapping %s:%s : %s\n",
+ data.dptr, key.dptr, tdb_errorstr(idmap_tdb)));
+
+ if (!deallocate_id(*id, isgroup) || tdb_delete(idmap_tdb, key))
+ DEBUG(0, ("Failed to rollback id mapping\n"));
+
+ result = False;
+ }
}
}
More information about the samba-technical
mailing list