s3:smbd: use session_global_id as session number for pam and utmp
authorGregor Beck <gbeck@sernet.de>
Thu, 23 Aug 2012 13:21:06 +0000 (15:21 +0200)
committerMichael Adam <obnox@samba.org>
Fri, 19 Oct 2012 10:15:00 +0000 (12:15 +0200)
Signed-off-by: Michael Adam <obnox@samba.org>
Signed-off-by: Stefan Metzmacher <metze@samba.org>
source3/include/local.h
source3/smbd/session.c
source3/smbd/utmp.c

index 02e6b43673eb70fb79ae16fef851a296b77c6d6e..a87ab8f100d7ae7cf40289c9033b44a718fd7367 100644 (file)
 /* Minimum length of allowed password when changing UNIX password. */
 #define MINPASSWDLENGTH 5
 
-/* maximum ID number used for session control. This cannot be larger
-   than 62*62 for the current code */
-#define MAX_SESSION_ID 3000
-
-/* For the benifit of PAM and the 'session exec' scripts, we fake up a terminal
-   name. This can be in one of two forms:  The first for systems not using
-   utmp (and therefore not constrained as to length or the need for a number
-   < 3000 or so) and the second for systems with this 'well behaved terminal
-   like name' constraint.
-*/
-
-#ifndef SESSION_TEMPLATE
-/* Paramaters are 'pid' and 'vuid' */
-#define SESSION_TEMPLATE "smb/%lu/%llu"
-#endif
-
-#ifndef SESSION_UTMP_TEMPLATE
-#define SESSION_UTMP_TEMPLATE "smb/%d"
-#endif
-
 /* the maximum age in seconds of a password. Should be a lp_ parameter */
 #define MAX_PASSWORD_AGE (21*24*60*60)
 
index abb1e316bca67addd3b112ea2339cbdbc4686a2e..6b0263e12233eba376a325678acb06e8868e1bc5 100644 (file)
@@ -46,7 +46,6 @@ bool session_claim(struct smbXsrv_session *session)
        struct smbd_server_connection *sconn = session->connection->sconn;
        struct server_id pid = messaging_server_id(sconn->msg_ctx);
        TDB_DATA data;
-       int i = 0;
        struct sessionid sessionid;
        fstring keystr;
        struct db_record *rec;
@@ -67,77 +66,21 @@ bool session_claim(struct smbXsrv_session *session)
 
        ZERO_STRUCT(sessionid);
 
+       sessionid.id_num = session->global->session_global_id;
+
        data.dptr = NULL;
        data.dsize = 0;
 
-       if (lp_utmp()) {
+       snprintf(keystr, sizeof(keystr), "ID/%u", sessionid.id_num);
+       snprintf(sessionid.id_str, sizeof(sessionid.id_str),
+                "smb/%u", sessionid.id_num);
 
-               for (i=1;i<MAX_SESSION_ID;i++) {
-
-                       /*
-                        * This is very inefficient and needs fixing -- vl
-                        */
-
-                       struct server_id sess_pid;
-                       TDB_DATA value;
-
-                       snprintf(keystr, sizeof(keystr), "ID/%d", i);
-
-                       rec = sessionid_fetch_record(NULL, keystr);
-                       if (rec == NULL) {
-                               DEBUG(1, ("Could not lock \"%s\"\n", keystr));
-                               return False;
-                       }
-
-                       value = dbwrap_record_get_value(rec);
-
-                       if (value.dsize != sizeof(sessionid)) {
-                               DEBUG(1, ("Re-using invalid record\n"));
-                               break;
-                       }
-
-                       memcpy(&sess_pid,
-                              ((char *)value.dptr)
-                              + offsetof(struct sessionid, pid),
-                              sizeof(sess_pid));
-
-                       if (!process_exists(sess_pid)) {
-                               DEBUG(5, ("%s has died -- re-using session\n",
-                                         procid_str_static(&sess_pid)));
-                               break;
-                       }
-
-                       TALLOC_FREE(rec);
-               }
-
-               if (i == MAX_SESSION_ID) {
-                       SMB_ASSERT(rec == NULL);
-                       DEBUG(1,("session_claim: out of session IDs "
-                                "(max is %d)\n", MAX_SESSION_ID));
-                       return False;
-               }
-
-               snprintf(sessionid.id_str, sizeof(sessionid.id_str),
-                        SESSION_UTMP_TEMPLATE, i);
-       } else
-       {
-               snprintf(keystr, sizeof(keystr), "ID/%s/%llu",
-                        procid_str_static(&pid),
-                        (unsigned long long)vuser->vuid);
-
-               rec = sessionid_fetch_record(NULL, keystr);
-               if (rec == NULL) {
-                       DEBUG(1, ("Could not lock \"%s\"\n", keystr));
-                       return False;
-               }
-
-               snprintf(sessionid.id_str, sizeof(sessionid.id_str),
-                        SESSION_TEMPLATE, (long unsigned int)getpid(),
-                        (unsigned long long)vuser->vuid);
+       rec = sessionid_fetch_record(NULL, keystr);
+       if (rec == NULL) {
+               DEBUG(1, ("Could not lock \"%s\"\n", keystr));
+               return False;
        }
 
-       SMB_ASSERT(rec != NULL);
-
        raddr = tsocket_address_inet_addr_string(session->connection->remote_address,
                                                 talloc_tos());
        if (raddr == NULL) {
@@ -149,7 +92,6 @@ bool session_claim(struct smbXsrv_session *session)
 
        fstrcpy(sessionid.username, vuser->session_info->unix_info->unix_name);
        fstrcpy(sessionid.hostname, sconn->remote_hostname);
-       sessionid.id_num = i;  /* Only valid for utmp sessions */
        sessionid.pid = pid;
        sessionid.uid = vuser->session_info->unix_token->uid;
        sessionid.gid = vuser->session_info->unix_token->gid;
index bb48d36946533610abb43ad9cdd0e7bfe2377414..0dc1917bfe27592bb2546edc6b9880b65017002e 100644 (file)
@@ -472,22 +472,23 @@ static int ut_id_encode(int i, char *fourbyte)
        int nbase;
        const char *ut_id_encstr = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
 
-       fourbyte[0] = 'S';
-       fourbyte[1] = 'M';
-
 /*
- * Encode remaining 2 bytes from 'i'.
  * 'ut_id_encstr' is the character set on which modulo arithmetic is done.
  * Example: digits would produce the base-10 numbers from '001'.
  */
        nbase = strlen(ut_id_encstr);
 
+       fourbyte[0] = ut_id_encstr[i % nbase];
+       i /= nbase;
+       fourbyte[1] = ut_id_encstr[i % nbase];
+       i /= nbase;
        fourbyte[3] = ut_id_encstr[i % nbase];
        i /= nbase;
        fourbyte[2] = ut_id_encstr[i % nbase];
        i /= nbase;
 
-       return(i);      /* 0: good; else overflow */
+       /* we do not care about overflows as i is a random number */
+       return 0;
 }
 #endif /* defined(HAVE_UT_UT_ID) */
 
@@ -517,11 +518,6 @@ static bool sys_utmp_fill(struct utmp *u,
         * ut_line:
         *      If size limit proves troublesome, then perhaps use "ut_id_encode()".
         */
-       if (strlen(id_str) > sizeof(u->ut_line)) {
-               DEBUG(1,("id_str [%s] is too long for %lu char utmp field\n",
-                        id_str, (unsigned long)sizeof(u->ut_line)));
-               return False;
-       }
        utmp_strcpy(u->ut_line, id_str, sizeof(u->ut_line));
 
 #if defined(HAVE_UT_UT_PID)