summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/auth/auth_util.c180
-rw-r--r--source3/auth/proto.h3
-rw-r--r--source3/auth/server_info.c34
-rw-r--r--source3/include/auth.h49
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;