diff --git a/include/net-snmp/library/snmp_api.h b/include/net-snmp/library/snmp_api.h
index 9a3d1a4838..6de3c18745 100644
--- a/include/net-snmp/library/snmp_api.h
+++ b/include/net-snmp/library/snmp_api.h
@@ -180,6 +180,7 @@ typedef struct request_list {
 
 #define SNMP_DETAIL_SIZE        512
 
+#define SNMP_FLAGS_SESSION_USER    0x1000
 #define SNMP_FLAGS_UDP_BROADCAST   0x800
 #define SNMP_FLAGS_RESP_CALLBACK   0x400      /* Additional callback on response */
 #define SNMP_FLAGS_USER_CREATED    0x200      /* USM user has been created */
diff --git a/include/net-snmp/types.h b/include/net-snmp/types.h
index 0d9eeb166f..eb06b1232c 100644
--- a/include/net-snmp/types.h
+++ b/include/net-snmp/types.h
@@ -418,6 +418,11 @@ struct snmp_session {
      * XXX: or should we add a new field into this structure?
      */
     void           *myvoid;
+
+    /**
+     * session specific user
+     */
+    struct usmUser *sessUser;
 };
 
 typedef struct netsnmp_index_s {
diff --git a/snmplib/snmp_api.c b/snmplib/snmp_api.c
index a90ab31b0c..2bd26002cd 100644
--- a/snmplib/snmp_api.c
+++ b/snmplib/snmp_api.c
@@ -786,7 +786,7 @@ snmp_sess_init(netsnmp_session * session)
     session->securityModel = SNMP_DEFAULT_SECMODEL;
     session->rcvMsgMaxSize = netsnmp_max_send_msg_size();
     session->sndMsgMaxSize = netsnmp_max_send_msg_size();
-    session->flags |= SNMP_FLAGS_DONT_PROBE;
+    session->flags |= SNMP_FLAGS_DONT_PROBE | SNMP_FLAGS_SESSION_USER;
 }
 
 
@@ -1923,6 +1923,7 @@ void netsnmp_cleanup_session(netsnmp_session *s)
 #ifndef NETSNMP_NO_TRAP_STATS
     SNMP_FREE(s->trap_stats);
 #endif /* NETSNMP_NO_TRAP_STATS */
+    usm_free_user(s->sessUser);
 }
 
 /*
diff --git a/snmplib/snmpusm.c b/snmplib/snmpusm.c
index 3a37848ebd..ed05875e04 100644
--- a/snmplib/snmpusm.c
+++ b/snmplib/snmpusm.c
@@ -501,8 +501,10 @@ usm_get_user_from_list(const u_char *engineID, size_t engineIDLen,
     /*
      * return "" user used to facilitate engineID discovery
      */
-    if (use_default && !strcmp(name, ""))
+    if (use_default && !strcmp(name, "")) {
+        DEBUGMSGTL(("usm", "return noNameUser\n"));
         return noNameUser;
+    }
     return NULL;
 }
 
@@ -1427,11 +1429,16 @@ usm_generate_out_msg(int msgProcModel,  /* (UNUSED) */
                       * * USM if needed.
                       */
                      size_t scopedPduLen,       /* IN - scopedPdu length. */
-                     const void *secStateRef, /* IN */
+                     const void *secStateRef,   /* IN */
                      /*
                       * secStateRef, pointer to cached info provided only for
                       * * Response, otherwise NULL.
                       */
+                     const u_long sessFlags,    /* IN */
+                     /*
+                      * sessFlags, state of session.
+                      */
+                     struct usmUser *sessUser,  /* IN - pointer to current session user. */
                      u_char * secParams,        /* OUT */
                      /*
                       * BER encoded securityParameters pointer to offset within
@@ -1533,7 +1540,11 @@ usm_generate_out_msg(int msgProcModel,  /* (UNUSED) */
          * we do allow an unknown user name for
          * unauthenticated requests. 
          */
-        user = usm_get_user2(secEngineID, secEngineIDLen, secName, secNameLen);
+        if ((sessFlags & SNMP_FLAGS_SESSION_USER) && sessUser)
+            user = sessUser;
+        else
+            user = usm_get_user2(secEngineID, secEngineIDLen, secName, secNameLen);
+
         if (user == NULL && secLevel != SNMP_SEC_LEVEL_NOAUTH) {
             DEBUGMSGTL(("usm", "Unknown User(%s)\n", secName));
             return SNMPERR_USM_UNKNOWNSECURITYNAME;
@@ -1905,6 +1916,7 @@ usm_secmod_generate_out_msg(struct snmp_secmod_outgoing_params *parms)
                                 parms->secLevel,
                                 parms->scopedPdu, parms->scopedPduLen,
                                 parms->secStateRef,
+                                parms->session->flags, parms->session->sessUser,
                                 parms->secParams, parms->secParamsLen,
                                 parms->wholeMsg, parms->wholeMsgLen);
 }
@@ -1938,6 +1950,12 @@ usm_rgenerate_out_msg(int msgProcModel, /* (UNUSED) */
                        * secStateRef, pointer to cached info provided only for
                        * * Response, otherwise NULL.
                        */
+                     const u_long sessFlags,    /* IN */
+                     /*
+                      * sessFlags, state of session.
+                      */
+                     struct usmUser *sessUser,  /* IN - pointer to current session user. */
+
                       u_char ** wholeMsg,       /*  IN/OUT  */
                       /*
                        * Points at the pointer to the packet buffer, which might get extended
@@ -2029,7 +2047,11 @@ usm_rgenerate_out_msg(int msgProcModel, /* (UNUSED) */
          * we do allow an unknown user name for
          * unauthenticated requests. 
          */
-        user = usm_get_user2(secEngineID, secEngineIDLen, secName, secNameLen);
+        if ((sessFlags & SNMP_FLAGS_SESSION_USER) && sessUser)
+            user = sessUser;
+        else
+            user = usm_get_user2(secEngineID, secEngineIDLen, secName, secNameLen);
+
         if (user == NULL && secLevel != SNMP_SEC_LEVEL_NOAUTH) {
             DEBUGMSGTL(("usm", "Unknown User\n"));
             return SNMPERR_USM_UNKNOWNSECURITYNAME;
@@ -2415,6 +2437,7 @@ usm_secmod_rgenerate_out_msg(struct snmp_secmod_outgoing_params *parms)
                                  parms->secLevel,
                                  parms->scopedPdu, parms->scopedPduLen,
                                  parms->secStateRef,
+                                 parms->session->flags, parms->session->sessUser,
                                  parms->wholeMsg, parms->wholeMsgLen,
                                  parms->wholeMsgOffset);
 }
@@ -3068,12 +3091,16 @@ usm_process_in_msg(int msgProcModel,    /* (UNUSED) */
      * Locate the User record.
      * If the user/engine ID is unknown, report this as an error.
      */
-    if ((user = usm_get_user_from_list(secEngineID, *secEngineIDLen,
+    if (sess && (sess->flags & SNMP_FLAGS_SESSION_USER) && sess->sessUser)
+        user = sess->sessUser;
+    else
+        user = usm_get_user_from_list(secEngineID, *secEngineIDLen,
                                        secName, *secNameLen, userList,
                                        (((sess && sess->isAuthoritative ==
                                           SNMP_SESS_AUTHORITATIVE) ||
-                                         (!sess)) ? 0 : 1)))
-        == NULL) {
+                                         (!sess)) ? 0 : 1));
+
+    if (user == NULL) {
         DEBUGMSGTL(("usm", "Unknown User(%s)\n", secName));
         snmp_increment_statistic(STAT_USMSTATSUNKNOWNUSERNAMES);
         error = SNMPERR_USM_UNKNOWNSECURITYNAME;
@@ -3601,11 +3628,16 @@ usm_create_user_from_session(netsnmp_session * session)
      * now that we have the engineID, create an entry in the USM list
      * for this user using the information in the session 
      */
-    user = usm_get_user_from_list(session->securityEngineID,
-                                  session->securityEngineIDLen,
-                                  session->securityName,
-                                  session->securityNameLen,
-                                  usm_get_userList(), 0);
+    if ((session->flags & SNMP_FLAGS_SESSION_USER) == 0)
+        user = usm_get_user_from_list(session->securityEngineID,
+                                      session->securityEngineIDLen,
+                                      session->securityName,
+                                      session->securityNameLen,
+                                      usm_get_userList(), 0);
+    else
+        user = NULL;
+
+
     if (NULL != user) {
         DEBUGMSGTL(("usm", "user exists x=%p\n", user));
     } else {
@@ -3745,9 +3777,16 @@ usm_create_user_from_session(netsnmp_session * session)
          */
         user->userStatus = RS_ACTIVE;
         user->userStorageType = ST_READONLY;
-        usm_add_user(user);
+
+        if (SNMP_FLAGS_SESSION_USER == (session->flags & SNMP_FLAGS_SESSION_USER)) {
+            if (session->sessUser)
+                usm_free_user(session->sessUser);
+            session->sessUser = user;
+        } else
+            usm_add_user(user);
     }
-    DEBUGMSGTL(("9:usm", "user created\n"));
+    DEBUGMSGTL(("9:usm", "user created and stored in %s\n", ((session->flags & SNMP_FLAGS_SESSION_USER) ? "session" :
+            "local store")));
 
     return SNMPERR_SUCCESS;
 
@@ -3764,7 +3803,7 @@ usm_create_user_from_session_hook(struct session_list *slp,
 }
 
 static int
-usm_build_probe_pdu(netsnmp_pdu **pdu)
+usm_build_probe_pdu(netsnmp_pdu **pdu, netsnmp_session *session)
 {
     struct usmUser *user;
 
@@ -3802,7 +3841,12 @@ usm_build_probe_pdu(netsnmp_pdu **pdu)
         user->privProtocolLen = OID_LENGTH(usmNoPrivProtocol);
         user->privProtocol =
             snmp_duplicate_objid(usmNoPrivProtocol, user->privProtocolLen);
-        usm_add_user(user);
+        if (session->flags & SNMP_FLAGS_SESSION_USER) {
+            if (session->sessUser)
+                usm_free_user(session->sessUser);
+            session->sessUser = user;
+        } else
+            usm_add_user(user);
     }
     return 0;
 }
@@ -3813,7 +3857,7 @@ static int usm_discover_engineid(struct session_list *slp,
     netsnmp_pdu    *pdu = NULL, *response = NULL;
     int status, i;
 
-    if (usm_build_probe_pdu(&pdu) != 0) {
+    if (usm_build_probe_pdu(&pdu, session) != 0) {
         DEBUGMSGTL(("snmp_api", "unable to create probe PDU\n"));
         return SNMP_ERR_GENERR;
     }
