diff options
-rw-r--r-- | source3/auth/auth_util.c | 180 | ||||
-rw-r--r-- | source3/auth/proto.h | 3 | ||||
-rw-r--r-- | source3/auth/server_info.c | 34 | ||||
-rw-r--r-- | source3/include/auth.h | 49 |
4 files changed, 266 insertions, 0 deletions
diff --git a/source3/auth/auth_util.c b/source3/auth/auth_util.c index 5553300ad1..a8c737dd88 100644 --- a/source3/auth/auth_util.c +++ b/source3/auth/auth_util.c @@ -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 diff --git a/source3/auth/proto.h b/source3/auth/proto.h index 8ff9fa9b99..8bc2c6e458 100644 --- a/source3/auth/proto.h +++ b/source3/auth/proto.h @@ -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, diff --git a/source3/auth/server_info.c b/source3/auth/server_info.c index a53e556d28..12026060bd 100644 --- a/source3/auth/server_info.c +++ b/source3/auth/server_info.c @@ -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. diff --git a/source3/include/auth.h b/source3/include/auth.h index 4f7cb9bb14..b1e5c32c36 100644 --- a/source3/include/auth.h +++ b/source3/include/auth.h @@ -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; |