s3:auth: add make_{server,session}_info_anonymous()
authorStefan Metzmacher <metze@samba.org>
Fri, 2 Mar 2018 13:39:44 +0000 (14:39 +0100)
committerRalph Boehme <slow@samba.org>
Thu, 15 Mar 2018 20:54:17 +0000 (21:54 +0100)
It's important to have them separated from make_{server,session}_info_guest(),
because there's a fundamental difference between anonymous (the client requested
no authentication) and guest (the server lies about the authentication failure).

The following is the difference between guest and anonymous token:

             security_token: struct security_token
-                num_sids                 : 0x0000000a (10)
-                sids: ARRAY(10)
-                    sids                     : S-1-5-21-3793881525-3372187982-3724979742-501
-                    sids                     : S-1-5-21-3793881525-3372187982-3724979742-514
-                    sids                     : S-1-22-2-65534
-                    sids                     : S-1-22-2-65533
+                num_sids                 : 0x00000009 (9)
+                sids: ARRAY(9)
+                    sids                     : S-1-5-7
                     sids                     : S-1-1-0
                     sids                     : S-1-5-2
-                    sids                     : S-1-5-32-546
                     sids                     : S-1-22-1-65533
+                    sids                     : S-1-22-2-65534
+                    sids                     : S-1-22-2-100004
                     sids                     : S-1-22-2-100002
                     sids                     : S-1-22-2-100003
+                    sids                     : S-1-22-2-65533
                 privilege_mask           : 0x0000000000000000 (0)

...

         unix_token               : *
             unix_token: struct security_unix_token
                 uid                      : 0x000000000000fffd (65533)
                 gid                      : 0x000000000000fffe (65534)
-                ngroups                  : 0x00000004 (4)
-                groups: ARRAY(4)
+                ngroups                  : 0x00000005 (5)
+                groups: ARRAY(5)
                     groups                   : 0x000000000000fffe (65534)
-                    groups                   : 0x000000000000fffd (65533)
+                    groups                   : 0x00000000000186a4 (100004)
                     groups                   : 0x00000000000186a2 (100002)
                     groups                   : 0x00000000000186a3 (100003)
+                    groups                   : 0x000000000000fffd (65533)

             info: struct auth_user_info
                 account_name             : *
-                    account_name             : 'nobody'
+                    account_name             : 'ANONYMOUS LOGON'
                 user_principal_name      : NULL
                 user_principal_constructed: 0x00 (0)
                 domain_name              : *
-                    domain_name              : 'SAMBA-TEST'
+                    domain_name              : 'NT AUTHORITY'
                 dns_domain_name          : NULL
-                full_name                : NULL
-                logon_script             : NULL
-                profile_path             : NULL
-                home_directory           : NULL
-                home_drive               : NULL
-                logon_server             : NULL
+                full_name                : *
+                    full_name                : 'Anonymous Logon'
+                logon_script             : *
+                    logon_script             : ''
+                profile_path             : *
+                    profile_path             : ''
+                home_directory           : *
+                    home_directory           : ''
+                home_drive               : *
+                    home_drive               : ''
+                logon_server             : *
+                    logon_server             : 'LOCALNT4DC2'
                 last_logon               : NTTIME(0)
                 last_logoff              : NTTIME(0)
                 acct_expiry              : NTTIME(0)
                 last_password_change     : NTTIME(0)
                 allow_password_change    : NTTIME(0)
                 force_password_change    : NTTIME(0)
                 logon_count              : 0x0000 (0)
                 bad_password_count       : 0x0000 (0)
-                acct_flags               : 0x00000000 (0)
+                acct_flags               : 0x00000010 (16)
                 authenticated            : 0x00 (0)
             security_token: struct security_token
                 num_sids                 : 0x00000006 (6)
                 sids: ARRAY(6)
+                    sids                     : S-1-5-7
+                    sids                     : S-1-1-0
+                    sids                     : S-1-5-2
                     sids                     : S-1-22-1-65533
                     sids                     : S-1-22-2-65534
                     sids                     : S-1-22-2-65533
-                    sids                     : S-1-1-0
-                    sids                     : S-1-5-2
-                    sids                     : S-1-5-32-546
                 privilege_mask           : 0x0000000000000000 (0)

BUG: https://bugzilla.samba.org/show_bug.cgi?id=13328

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Ralph Boehme <slow@samba.org>
source3/auth/auth_util.c
source3/auth/proto.h

index 8b7630fd5d7ded124fa684bd304efcbf5a9ccea1..3b951e7fa0a6a2d1c9e3610801a887f899a5f5da 100644 (file)
@@ -1462,6 +1462,87 @@ done:
        return status;
 }
 
+static NTSTATUS make_new_session_info_anonymous(TALLOC_CTX *mem_ctx,
+                                       struct auth_session_info **session_info)
+{
+       TALLOC_CTX *frame = talloc_stackframe();
+       const char *guest_account = lp_guest_account();
+       struct auth_user_info_dc *user_info_dc = NULL;
+       struct passwd *pwd = NULL;
+       uint32_t hint_flags = 0;
+       uint32_t session_info_flags = 0;
+       NTSTATUS status;
+
+       /*
+        * We use the guest account for the unix token
+        * while we use a true anonymous nt token.
+        *
+        * It's very important to have a separate
+        * nt token for anonymous.
+        */
+
+       pwd = Get_Pwnam_alloc(frame, guest_account);
+       if (pwd == NULL) {
+               DBG_ERR("Unable to locate guest account [%s]!\n",
+                       guest_account);
+               status = NT_STATUS_NO_SUCH_USER;
+               goto done;
+       }
+
+       status = auth_anonymous_user_info_dc(frame, lp_netbios_name(),
+                                            &user_info_dc);
+       if (!NT_STATUS_IS_OK(status)) {
+               DEBUG(0, ("auth_anonymous_user_info_dc failed: %s\n",
+                         nt_errstr(status)));
+               goto done;
+       }
+
+       /*
+        * Note we don't pass AUTH3_UNIX_HINT_QUALIFIED_NAME
+        * nor AUTH3_UNIX_HINT_ISOLATED_NAME here
+        * as we want the unix name be found by getpwuid_alloc().
+        */
+
+       status = auth3_user_info_dc_add_hints(user_info_dc,
+                                             pwd->pw_uid,
+                                             pwd->pw_gid,
+                                             hint_flags);
+       if (!NT_STATUS_IS_OK(status)) {
+               DEBUG(0, ("auth3_user_info_dc_add_hints failed: %s\n",
+                         nt_errstr(status)));
+               goto done;
+       }
+
+       /*
+        * In future we may want to remove
+        * AUTH_SESSION_INFO_DEFAULT_GROUPS.
+        *
+        * Similar to Windows with EveryoneIncludesAnonymous
+        * and RestrictAnonymous.
+        *
+        * We may introduce AUTH_SESSION_INFO_ANON_WORLD...
+        *
+        * But for this is required to keep the existing tests
+        * working.
+        */
+       session_info_flags |= AUTH_SESSION_INFO_DEFAULT_GROUPS;
+       session_info_flags |= AUTH_SESSION_INFO_SIMPLE_PRIVILEGES;
+       session_info_flags |= AUTH_SESSION_INFO_UNIX_TOKEN;
+       status = auth3_session_info_create(mem_ctx, user_info_dc,
+                                          "",
+                                          session_info_flags,
+                                          session_info);
+       if (!NT_STATUS_IS_OK(status)) {
+               DEBUG(0, ("auth3_session_info_create failed: %s\n",
+                         nt_errstr(status)));
+               goto done;
+       }
+
+done:
+       TALLOC_FREE(frame);
+       return status;
+}
+
 /****************************************************************************
   Fake a auth_session_info just from a username (as a
   session_info structure, with create_local_token() already called on
@@ -1642,6 +1723,7 @@ bool session_info_set_session_key(struct auth_session_info *info,
 }
 
 static struct auth_session_info *guest_info = NULL;
+static struct auth_session_info *anonymous_info = NULL;
 
 static struct auth_serversupplied_info *guest_server_info = NULL;
 
@@ -1655,7 +1737,17 @@ bool init_guest_session_info(TALLOC_CTX *mem_ctx)
        status = make_new_session_info_guest(mem_ctx,
                                             &guest_info,
                                             &guest_server_info);
-       return NT_STATUS_IS_OK(status);
+       if (!NT_STATUS_IS_OK(status)) {
+               return false;
+       }
+
+       status = make_new_session_info_anonymous(mem_ctx,
+                                                &anonymous_info);
+       if (!NT_STATUS_IS_OK(status)) {
+               return false;
+       }
+
+       return true;
 }
 
 NTSTATUS make_server_info_guest(TALLOC_CTX *mem_ctx,
@@ -1676,6 +1768,51 @@ NTSTATUS make_session_info_guest(TALLOC_CTX *mem_ctx,
        return (*session_info != NULL) ? NT_STATUS_OK : NT_STATUS_NO_MEMORY;
 }
 
+NTSTATUS make_server_info_anonymous(TALLOC_CTX *mem_ctx,
+                                   struct auth_serversupplied_info **server_info)
+{
+       if (anonymous_info == NULL) {
+               return NT_STATUS_UNSUCCESSFUL;
+       }
+
+       /*
+        * This is trickier than it would appear to need to be because
+        * we are trying to avoid certain costly operations when the
+        * structure is converted to a 'auth_session_info' again in
+        * create_local_token()
+        *
+        * We use a guest server_info, but with the anonymous session info,
+        * which means create_local_token() will return a copy
+        * of the anonymous token.
+        *
+        * The server info is just used as legacy in order to
+        * keep existing code working. Maybe some debug messages
+        * will still refer to guest instead of anonymous.
+        */
+       *server_info = copy_session_info_serverinfo_guest(mem_ctx, anonymous_info,
+                                                         guest_server_info);
+       if (*server_info == NULL) {
+               return NT_STATUS_NO_MEMORY;
+       }
+
+       return NT_STATUS_OK;
+}
+
+NTSTATUS make_session_info_anonymous(TALLOC_CTX *mem_ctx,
+                                    struct auth_session_info **session_info)
+{
+       if (anonymous_info == NULL) {
+               return NT_STATUS_UNSUCCESSFUL;
+       }
+
+       *session_info = copy_session_info(mem_ctx, anonymous_info);
+       if (*session_info == NULL) {
+               return NT_STATUS_NO_MEMORY;
+       }
+
+       return NT_STATUS_OK;
+}
+
 static struct auth_session_info *system_info = NULL;
 
 NTSTATUS init_system_session_info(TALLOC_CTX *mem_ctx)
index dc59fa969ac3130ca5776e3dd1c1ab1491b3a145..e4a6830eecbaca318e4b4868df0feec8687d1a56 100644 (file)
@@ -280,6 +280,10 @@ NTSTATUS make_server_info_guest(TALLOC_CTX *mem_ctx,
                                struct auth_serversupplied_info **server_info);
 NTSTATUS make_session_info_guest(TALLOC_CTX *mem_ctx,
                                struct auth_session_info **server_info);
+NTSTATUS make_server_info_anonymous(TALLOC_CTX *mem_ctx,
+                                   struct auth_serversupplied_info **server_info);
+NTSTATUS make_session_info_anonymous(TALLOC_CTX *mem_ctx,
+                                    struct auth_session_info **psession_info);
 NTSTATUS make_session_info_system(TALLOC_CTX *mem_ctx,
                                 struct auth_session_info **session_info);
 const struct auth_session_info *get_session_info_system(void);