s3-auth Add struct auth3_session_info to aid transition to auth_session info
authorAndrew Bartlett <abartlet@samba.org>
Fri, 15 Jul 2011 01:38:49 +0000 (11:38 +1000)
committerAndrew Bartlett <abartlet@samba.org>
Tue, 19 Jul 2011 23:17:10 +0000 (09:17 +1000)
This will allow a gradual conversion of the required elements from the
current struct auth_serversupplied_info.

This commit adds the structure definition and some helper functions to
copy between the two structures.

At this stage these structures and functions are IDENTICAL to the
existing code, and so show the past history of that code.  The plan is
to slowly modify them over the course of the patch series, so that the
changes being made a clear.

By using a seperate structure to auth_serversupplied_info we can
remove elements that are not needed after the authentication, and we
can choose a layout that best reflects the needs of runtime users,
rather than the internals of the authentication subsystem.

By eventually using the auth_session_info from auth.idl, we will gain
a single session authorization structure across the whole codebase,
allowing more code to be shared, and a much more transparent process
for forwarding authorization credentials over the named pipe proxy.

Andrew Bartlett

Signed-off-by: Andrew Tridgell <tridge@samba.org>
source3/auth/auth_util.c
source3/auth/proto.h
source3/auth/server_info.c
source3/include/auth.h

index 5553300ad1fac2f90d7f8cf96f37d7dc45ac9bc0..a8c737dd8835e21849abf531779d681ed223e64f 100644 (file)
@@ -34,6 +34,9 @@
 #undef DBGC_CLASS
 #define DBGC_CLASS DBGC_AUTH
 
+static struct auth3_session_info *copy_serverinfo_session_info(TALLOC_CTX *mem_ctx,
+                                                              const struct auth_serversupplied_info *src);
+
 /****************************************************************************
  Create a UNIX user on demand.
 ****************************************************************************/
@@ -965,6 +968,183 @@ struct auth_serversupplied_info *copy_serverinfo(TALLOC_CTX *mem_ctx,
        return dst;
 }
 
+static struct auth_serversupplied_info *copy_session_info_serverinfo(TALLOC_CTX *mem_ctx,
+                                                             const struct auth3_session_info *src)
+{
+       struct auth_serversupplied_info *dst;
+
+       dst = make_server_info(mem_ctx);
+       if (dst == NULL) {
+               return NULL;
+       }
+
+       dst->guest = src->guest;
+       dst->system = src->system;
+       dst->utok.uid = src->utok.uid;
+       dst->utok.gid = src->utok.gid;
+       dst->utok.ngroups = src->utok.ngroups;
+       if (src->utok.ngroups != 0) {
+               dst->utok.groups = (gid_t *)talloc_memdup(
+                       dst, src->utok.groups,
+                       sizeof(gid_t)*dst->utok.ngroups);
+       } else {
+               dst->utok.groups = NULL;
+       }
+
+       if (src->security_token) {
+               dst->security_token = dup_nt_token(dst, src->security_token);
+               if (!dst->security_token) {
+                       TALLOC_FREE(dst);
+                       return NULL;
+               }
+       }
+
+       dst->session_key = data_blob_talloc( dst, src->session_key.data,
+                                               src->session_key.length);
+
+       dst->lm_session_key = data_blob_talloc(dst, src->lm_session_key.data,
+                                               src->lm_session_key.length);
+
+       dst->info3 = copy_netr_SamInfo3(dst, src->info3);
+       if (!dst->info3) {
+               TALLOC_FREE(dst);
+               return NULL;
+       }
+       dst->extra = src->extra;
+
+       dst->unix_name = talloc_strdup(dst, src->unix_name);
+       if (!dst->unix_name) {
+               TALLOC_FREE(dst);
+               return NULL;
+       }
+
+       dst->sanitized_username = talloc_strdup(dst, src->sanitized_username);
+       if (!dst->sanitized_username) {
+               TALLOC_FREE(dst);
+               return NULL;
+       }
+
+       return dst;
+}
+
+static struct auth3_session_info *copy_serverinfo_session_info(TALLOC_CTX *mem_ctx,
+                                                       const struct auth_serversupplied_info *src)
+{
+       struct auth3_session_info *dst;
+
+       dst = make_auth3_session_info(mem_ctx);
+       if (dst == NULL) {
+               return NULL;
+       }
+
+       dst->guest = src->guest;
+       dst->system = src->system;
+       dst->utok.uid = src->utok.uid;
+       dst->utok.gid = src->utok.gid;
+       dst->utok.ngroups = src->utok.ngroups;
+       if (src->utok.ngroups != 0) {
+               dst->utok.groups = (gid_t *)talloc_memdup(
+                       dst, src->utok.groups,
+                       sizeof(gid_t)*dst->utok.ngroups);
+       } else {
+               dst->utok.groups = NULL;
+       }
+
+       if (src->security_token) {
+               dst->security_token = dup_nt_token(dst, src->security_token);
+               if (!dst->security_token) {
+                       TALLOC_FREE(dst);
+                       return NULL;
+               }
+       }
+
+       dst->session_key = data_blob_talloc( dst, src->session_key.data,
+                                               src->session_key.length);
+
+       dst->lm_session_key = data_blob_talloc(dst, src->lm_session_key.data,
+                                               src->lm_session_key.length);
+
+       dst->info3 = copy_netr_SamInfo3(dst, src->info3);
+       if (!dst->info3) {
+               TALLOC_FREE(dst);
+               return NULL;
+       }
+       dst->extra = src->extra;
+
+       dst->unix_name = talloc_strdup(dst, src->unix_name);
+       if (!dst->unix_name) {
+               TALLOC_FREE(dst);
+               return NULL;
+       }
+
+       dst->sanitized_username = talloc_strdup(dst, src->sanitized_username);
+       if (!dst->sanitized_username) {
+               TALLOC_FREE(dst);
+               return NULL;
+       }
+
+       return dst;
+}
+
+struct auth3_session_info *copy_session_info(TALLOC_CTX *mem_ctx,
+                                            const struct auth3_session_info *src)
+{
+       struct auth3_session_info *dst;
+
+       dst = make_auth3_session_info(mem_ctx);
+       if (dst == NULL) {
+               return NULL;
+       }
+
+       dst->guest = src->guest;
+       dst->system = src->system;
+       dst->utok.uid = src->utok.uid;
+       dst->utok.gid = src->utok.gid;
+       dst->utok.ngroups = src->utok.ngroups;
+       if (src->utok.ngroups != 0) {
+               dst->utok.groups = (gid_t *)talloc_memdup(
+                       dst, src->utok.groups,
+                       sizeof(gid_t)*dst->utok.ngroups);
+       } else {
+               dst->utok.groups = NULL;
+       }
+
+       if (src->security_token) {
+               dst->security_token = dup_nt_token(dst, src->security_token);
+               if (!dst->security_token) {
+                       TALLOC_FREE(dst);
+                       return NULL;
+               }
+       }
+
+       dst->session_key = data_blob_talloc( dst, src->session_key.data,
+                                               src->session_key.length);
+
+       dst->lm_session_key = data_blob_talloc(dst, src->lm_session_key.data,
+                                               src->lm_session_key.length);
+
+       dst->info3 = copy_netr_SamInfo3(dst, src->info3);
+       if (!dst->info3) {
+               TALLOC_FREE(dst);
+               return NULL;
+       }
+       dst->extra = src->extra;
+
+       dst->unix_name = talloc_strdup(dst, src->unix_name);
+       if (!dst->unix_name) {
+               TALLOC_FREE(dst);
+               return NULL;
+       }
+
+       dst->sanitized_username = talloc_strdup(dst, src->sanitized_username);
+       if (!dst->sanitized_username) {
+               TALLOC_FREE(dst);
+               return NULL;
+       }
+
+       return dst;
+}
+
 /*
  * Set a new session key. Used in the rpc server where we have to override the
  * SMB level session key with SystemLibraryDTC
index 8ff9fa9b995ecac0dd8feffceceb91da62c3c372..8bc2c6e4588c424caa80e0dee3b981583b59b3ab 100644 (file)
@@ -168,6 +168,8 @@ NTSTATUS make_session_info_from_username(TALLOC_CTX *mem_ctx,
                                         struct auth_serversupplied_info **session_info);
 struct auth_serversupplied_info *copy_serverinfo(TALLOC_CTX *mem_ctx,
                                                 const struct auth_serversupplied_info *src);
+struct auth3_session_info *copy_session_info(TALLOC_CTX *mem_ctx,
+                                            const struct auth3_session_info *src);
 bool init_guest_info(void);
 NTSTATUS init_system_info(void);
 bool session_info_set_session_key(struct auth_serversupplied_info *info,
@@ -223,6 +225,7 @@ struct netr_SamInfo3;
 struct netr_SamInfo6;
 
 struct auth_serversupplied_info *make_server_info(TALLOC_CTX *mem_ctx);
+struct auth3_session_info *make_auth3_session_info(TALLOC_CTX *mem_ctx);
 NTSTATUS serverinfo_to_SamInfo2(struct auth_serversupplied_info *server_info,
                                uint8_t *pipe_session_key,
                                size_t pipe_session_key_len,
index a53e556d283d2b11fca194e8972c7a4dc4f6ee33..12026060bdbab9103d1e5bbff877091072494671 100644 (file)
@@ -63,6 +63,40 @@ struct auth_serversupplied_info *make_server_info(TALLOC_CTX *mem_ctx)
        return result;
 }
 
+/* FIXME: do we really still need this ? */
+static int auth3_session_info_dtor(struct auth3_session_info *session_info)
+{
+       TALLOC_FREE(session_info->info3);
+       ZERO_STRUCTP(session_info);
+       return 0;
+}
+
+/***************************************************************************
+ Make a server_info struct. Free with TALLOC_FREE().
+***************************************************************************/
+
+struct auth3_session_info *make_auth3_session_info(TALLOC_CTX *mem_ctx)
+{
+       struct auth3_session_info *result;
+
+       result = talloc_zero(mem_ctx, struct auth3_session_info);
+       if (result == NULL) {
+               DEBUG(0, ("talloc failed\n"));
+               return NULL;
+       }
+
+       talloc_set_destructor(result, auth3_session_info_dtor);
+
+       /* Initialise the uid and gid values to something non-zero
+          which may save us from giving away root access if there
+          is a bug in allocating these fields. */
+
+       result->utok.uid = -1;
+       result->utok.gid = -1;
+
+       return result;
+}
+
 /****************************************************************************
  inits a netr_SamInfo2 structure from an auth_serversupplied_info. sam2 must
  already be initialized and is used as the talloc parent for its members.
index 4f7cb9bb1487d1aab6727b571954e762352b963e..b1e5c32c363445dfe67212ad91204cd32bc1b8dd 100644 (file)
@@ -75,6 +75,55 @@ struct auth_serversupplied_info {
        char *sanitized_username;
 };
 
+struct auth3_session_info {
+       bool guest;
+       bool system;
+
+       struct security_unix_token utok;
+
+       /* NT group information taken from the info3 structure */
+
+       struct security_token *security_token;
+
+       /* This is the final session key, as used by SMB signing, and
+        * (truncated to 16 bytes) encryption on the SAMR and LSA pipes
+        * when over ncacn_np.
+        * It is calculated by NTLMSSP from the session key in the info3,
+        * and is  set from the Kerberos session key using
+        * krb5_auth_con_getremotesubkey().
+        *
+        * Bottom line, it is not the same as the session keys in info3.
+        */
+
+       DATA_BLOB session_key;
+       DATA_BLOB lm_session_key;
+
+       struct netr_SamInfo3 *info3;
+
+       /* this structure is filled *only* in pathological cases where the user
+        * sid or the primary group sid are not sids of the domain. Normally
+        * this happens only for unix accounts that have unix domain sids.
+        * This is checked only when info3.rid and/or info3.primary_gid are set
+        * to the special invalid value of 0xFFFFFFFF */
+       struct extra_auth_info extra;
+
+       /*
+        * This is a token from /etc/passwd and /etc/group
+        */
+       bool nss_token;
+
+       char *unix_name;
+
+       /*
+        * For performance reasons we keep an alpha_strcpy-sanitized version
+        * of the username around as long as the global variable current_user
+        * still exists. If we did not do keep this, we'd have to call
+        * alpha_strcpy whenever we do a become_user(), potentially on every
+        * smb request. See set_current_user_info.
+        */
+       char *sanitized_username;
+};
+
 struct auth_context {
        DATA_BLOB challenge;