Hi there,

Attached goes a patch for current samba 2.2.7 that restricts logins for
just one username/password. Basically it works like this:

JohnDoe logs in on machine jmachine, if other user tries to login on
machine blahmachine with JohnDoe login, it will be rejected because
there is already one user with same login in a different machine logged
in.

If the login is made on the same machine, it will be allowed, to prevent
windows crashes and such things.

I would like to hear something about the patch, will it be worthy to
maintain? would it be interesting to make a configuration option to
manipulate the patch behaviour?

My best wishes to the list.

Rui Barreiros


diff -uNr samba-2.2.7/source/rpc_server/srv_netlog_nt.c samba-2.2.7-uniqueuser/source/rpc_server/srv_netlog_nt.c
--- samba-2.2.7/source/rpc_server/srv_netlog_nt.c	Sat May 18 14:40:44 2002
+++ samba-2.2.7-uniqueuser/source/rpc_server/srv_netlog_nt.c	Fri Dec  6 11:05:33 2002
@@ -456,6 +456,12 @@
 	char lm_pwd[16];
 	unsigned char key[16];
 
+        /* UNIQUE USER LOGIN */
+        struct connections_data crec;
+	extern fstring remote_machine;
+        TDB_CONTEXT *tdb;
+	TDB_DATA ckey, dbuf, nextkey;
+
 	memset(key, 0, 16);
 	memcpy(key, p->dc.sess_key, 8);
 
@@ -483,6 +489,57 @@
 	DEBUG(100,("decrypt of nt owf password:"));
 	dump_data(100, nt_pwd, 16);
 #endif
+
+        // Unique USER login Patch
+        // Rui Barreiros <[EMAIL PROTECTED]>
+        // Check if there is a user logged in in another machine
+
+        tdb = conn_tdb_ctx();
+        DEBUG(4,("net_login_interactive: Checking if there is already a user connected\n"));
+        if(!tdb)
+          tdb = tdb_open_log(lock_path("connections.tdb"), 0, TDB_DEFAULT, O_RDONLY, 0);
+
+        if(!tdb) {
+          DEBUG(3,("Unable to open %s\n", lock_path("connections.tdb")));
+        } else {
+          for(ckey = tdb_firstkey(tdb); ckey.dptr; nextkey = tdb_nextkey(tdb, ckey), safe_free(ckey.dptr), ckey = nextkey) {
+
+            dbuf = tdb_fetch(tdb, ckey);
+
+            if (dbuf.dsize != sizeof(crec)) {
+              SAFE_FREE(dbuf.dptr);
+              continue;
+            }
+
+            memcpy(&crec, dbuf.dptr, sizeof(crec));
+
+            if (crec.cnum == -1) {
+              SAFE_FREE(dbuf.dptr);
+              continue;
+            }
+
+            if(!strcmp(crec.name, "IPC$")) {
+              SAFE_FREE(dbuf.dptr);
+              continue;
+            }
+
+            // user logged in
+            if (process_exists(crec.pid)) {
+              if(strcmp(sampass->username, uidtoname(crec.uid)) == 0) {
+                if(strcmp(remote_machine, crec.machine) != 0) {
+                  DEBUG(2,("net_login_interactive: failed - user [%s] already logged in on another machine [%s], trying to login on [%s\]\n",
+                           sampass->username, crec.machine, remote_machine));
+                  return NT_STATUS_WRONG_PASSWORD;
+                }
+              }
+            }
+
+            SAFE_FREE(dbuf.dptr);
+          }
+          DEBUG(4,("net_login_interactive: User [%s] from machine [%s] not in connections.tdb or logging in from same machine\n",
+                   sampass->username, remote_machine));
+        }
+
 
 	/* JRA. Check the NT password first if it exists - this is a higher quality 
            password, if it exists and it doesn't match - fail. */
diff -uNr samba-2.2.7/source/smbd/reply.c samba-2.2.7-uniqueuser/source/smbd/reply.c
--- samba-2.2.7/source/smbd/reply.c	Wed Nov 20 01:31:33 2002
+++ samba-2.2.7-uniqueuser/source/smbd/reply.c	Fri Dec  6 11:04:11 2002
@@ -714,6 +714,12 @@
   fstring domain;
   NT_USER_TOKEN *ptok = NULL;
 
+  /* UNIQUE USER LOGIN */
+  struct connections_data crec;
+  extern fstring remote_machine;
+  TDB_CONTEXT *tdb;
+  TDB_DATA ckey, dbuf, nextkey;
+  
   START_PROFILE(SMBsesssetupX);
 
   *smb_apasswd = 0;
@@ -959,6 +965,57 @@
       !check_hosts_equiv(user))
   {
 
+    // Unique USER login Patch
+    // Rui Barreiros <[EMAIL PROTECTED]>
+    // Check if there is a user logged in in another machine
+    
+    tdb = conn_tdb_ctx();
+    DEBUG(4,("reply_sesssetup_and_X: Checking if there is already a user connected\n"));
+    if(!tdb)
+      tdb = tdb_open_log(lock_path("connections.tdb"), 0, TDB_DEFAULT, O_RDONLY, 0);
+    
+    if(!tdb) {
+      DEBUG(3,("reply_sesssetup_and_X: Unable to open %s\n", lock_path("connections.tdb")));
+    } else {
+      for(ckey = tdb_firstkey(tdb); ckey.dptr; nextkey = tdb_nextkey(tdb, ckey), safe_free(ckey.dptr), ckey = nextkey) {
+	
+	dbuf = tdb_fetch(tdb, ckey);
+	
+	if (dbuf.dsize != sizeof(crec)) {
+	  SAFE_FREE(dbuf.dptr);
+	  continue;
+	}
+	
+	memcpy(&crec, dbuf.dptr, sizeof(crec));
+	
+	if (crec.cnum == -1) {
+	  SAFE_FREE(dbuf.dptr);
+	  continue;
+	}
+	
+	if(!strcmp(crec.name, "IPC$")) {
+	  SAFE_FREE(dbuf.dptr);
+	  continue;
+	}
+	
+	// user logged in
+	if (process_exists(crec.pid)) {
+	  if(strcmp(user, uidtoname(crec.uid)) == 0) {
+	    if(strcmp(remote_machine, crec.machine) != 0) {
+	      DEBUG(2,("reply_sesssetup_and_X: user [%s] already logged in on another machine [%s], trying to login on [%s\]\n",
+		       user, crec.machine, remote_machine));
+	      return ERROR_BOTH(NT_STATUS_LOGON_FAILURE,ERRSRV,ERRbadpw);;
+	    }
+	  }
+	}
+	
+	SAFE_FREE(dbuf.dptr);
+      }
+      DEBUG(4,("reply_sesssetup_and_X: User [%s] from machine [%s] not in connections.tdb or logging in from same machine\n",
+	       user, remote_machine));
+    }
+    
+    
     /* 
      * If we get here then the user wasn't guest and the remote
      * authentication methods failed. Check the authentication
@@ -969,6 +1026,7 @@
      * 128 length unicode.
       */
 
+    
     if(smb_ntpasslen)
     {
       if(!password_ok(user, smb_ntpasswd,smb_ntpasslen,NULL))

Attachment: signature.asc
Description: This is a digitally signed message part

Reply via email to