~ubuntu-branches/ubuntu/vivid/samba/vivid

« back to all changes in this revision

Viewing changes to source3/rpc_server/dcesrv_gssapi.c

  • Committer: Package Import Robot
  • Author(s): Chuck Short
  • Date: 2011-12-21 13:18:04 UTC
  • mfrom: (0.39.21 sid)
  • Revision ID: package-import@ubuntu.com-20111221131804-xtlr39wx6njehxxr
Tags: 2:3.6.1-3ubuntu1
* Merge from Debian testing.  Remaining changes:
  + debian/patches/VERSION.patch:
    - set SAMBA_VERSION_SUFFIX to Ubuntu.
  + debian/patches/error-trans.fix-276472:
    - Add the translation of Unix Error code -ENOTSUP to NT Error Code
    - NT_STATUS_NOT_SUPPORTED to prevent the Permission denied error.
  + debian/smb.conf:
    - add "(Samba, Ubuntu)" to server string.
    - comment out the default [homes] share, and add a comment about
      "valid users = %S" to show users how to restrict access to
      \\server\username to only username.
    - Set 'usershare allow guests', so that usershare admins are 
      allowed to create public shares in addition to authenticated
      ones.
    - add map to guest = Bad user, maps bad username to guest access.
  + debian/samba-common.config:
    - Do not change priority to high if dhclient3 is installed.
    - Use priority medium instead of high for the workgroup question.
  + debian/control:
    - Don't build against or suggest ctdb.
    - Add dependency on samba-common-bin to samba.
  + Add ufw integration:
    - Created debian/samba.ufw.profile
    - debian/rules, debian/samba.dirs, debian/samba.files: install
      profile
    - debian/control: have samba suggest ufw
  + Add apport hook:
    - Created debian/source_samba.py.
    - debian/rules, debian/samba.dirs, debian/samba-common-bin.files: install
  + Switch to upstart:
    - Add debian/samba.{nmbd,smbd}.upstart.
  + debian/samba.logrotate, debian/samba-common.dhcp, debian/samba.if-up:
    - Make them upstart compatible
  + debian/samba.postinst: 
    - Avoid scary pdbedit warnings on first import.
  + debian/samba-common.postinst: Add more informative error message for
    the case where smb.conf was manually deleted
  + debian/patches/fix-debuglevel-name-conflict.patch: don't use 'debug_level'
    as a global variable name in an NSS module 
  + Dropped:
    - debian/patches/error-trans.fix-276472
    - debian/patches/fix-debuglevel-name-conflict.patch

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 *  GSSAPI Acceptor
 
3
 *  DCERPC Server functions
 
4
 *  Copyright (C) Simo Sorce 2010.
 
5
 *
 
6
 *  This program is free software; you can redistribute it and/or modify
 
7
 *  it under the terms of the GNU General Public License as published by
 
8
 *  the Free Software Foundation; either version 3 of the License, or
 
9
 *  (at your option) any later version.
 
10
 *
 
11
 *  This program is distributed in the hope that it will be useful,
 
12
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
13
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
14
 *  GNU General Public License for more details.
 
15
 *
 
16
 *  You should have received a copy of the GNU General Public License
 
17
 *  along with this program; if not, see <http://www.gnu.org/licenses/>.
 
18
 */
 
19
 
 
20
 
 
21
#include "includes.h"
 
22
#include "rpc_server/dcesrv_gssapi.h"
 
23
#include "../librpc/gen_ndr/ndr_krb5pac.h"
 
24
#include "librpc/crypto/gse.h"
 
25
#include "auth.h"
 
26
 
 
27
NTSTATUS gssapi_server_auth_start(TALLOC_CTX *mem_ctx,
 
28
                                  bool do_sign,
 
29
                                  bool do_seal,
 
30
                                  bool is_dcerpc,
 
31
                                  DATA_BLOB *token_in,
 
32
                                  DATA_BLOB *token_out,
 
33
                                  struct gse_context **ctx)
 
34
{
 
35
        struct gse_context *gse_ctx = NULL;
 
36
        uint32_t add_flags = 0;
 
37
        NTSTATUS status;
 
38
 
 
39
        if (is_dcerpc) {
 
40
                add_flags = GSS_C_DCE_STYLE;
 
41
        }
 
42
 
 
43
        /* Let's init the gssapi machinery for this connection */
 
44
        /* passing a NULL server name means the server will try
 
45
         * to accept any connection regardless of the name used as
 
46
         * long as it can find a decryption key */
 
47
        /* by passing NULL, the code will attempt to set a default
 
48
         * keytab based on configuration options */
 
49
        status = gse_init_server(mem_ctx, do_sign, do_seal,
 
50
                                 add_flags, NULL, &gse_ctx);
 
51
        if (!NT_STATUS_IS_OK(status)) {
 
52
                DEBUG(0, ("Failed to init dcerpc gssapi server (%s)\n",
 
53
                          nt_errstr(status)));
 
54
                return status;
 
55
        }
 
56
 
 
57
        status = gse_get_server_auth_token(mem_ctx, gse_ctx,
 
58
                                           token_in, token_out);
 
59
        if (!NT_STATUS_IS_OK(status)) {
 
60
                DEBUG(0, ("Failed to parse initial client token (%s)\n",
 
61
                          nt_errstr(status)));
 
62
                goto done;
 
63
        }
 
64
 
 
65
        *ctx = gse_ctx;
 
66
        status = NT_STATUS_OK;
 
67
 
 
68
done:
 
69
        if (!NT_STATUS_IS_OK(status)) {
 
70
                TALLOC_FREE(gse_ctx);
 
71
        }
 
72
 
 
73
        return status;
 
74
}
 
75
 
 
76
NTSTATUS gssapi_server_step(struct gse_context *gse_ctx,
 
77
                            TALLOC_CTX *mem_ctx,
 
78
                            DATA_BLOB *token_in,
 
79
                            DATA_BLOB *token_out)
 
80
{
 
81
        NTSTATUS status;
 
82
 
 
83
        status = gse_get_server_auth_token(mem_ctx, gse_ctx,
 
84
                                           token_in, token_out);
 
85
        if (!NT_STATUS_IS_OK(status)) {
 
86
                return status;
 
87
        }
 
88
 
 
89
        if (gse_require_more_processing(gse_ctx)) {
 
90
                /* ask for next leg */
 
91
                return NT_STATUS_MORE_PROCESSING_REQUIRED;
 
92
        }
 
93
 
 
94
        return NT_STATUS_OK;
 
95
}
 
96
 
 
97
NTSTATUS gssapi_server_check_flags(struct gse_context *gse_ctx)
 
98
{
 
99
        return gse_verify_server_auth_flags(gse_ctx);
 
100
}
 
101
 
 
102
NTSTATUS gssapi_server_get_user_info(struct gse_context *gse_ctx,
 
103
                                     TALLOC_CTX *mem_ctx,
 
104
                                     struct client_address *client_id,
 
105
                                     struct auth_serversupplied_info **server_info)
 
106
{
 
107
        TALLOC_CTX *tmp_ctx;
 
108
        DATA_BLOB pac;
 
109
        struct PAC_DATA *pac_data;
 
110
        struct PAC_LOGON_INFO *logon_info = NULL;
 
111
        enum ndr_err_code ndr_err;
 
112
        unsigned int i;
 
113
        bool is_mapped;
 
114
        bool is_guest;
 
115
        char *princ_name;
 
116
        char *ntuser;
 
117
        char *ntdomain;
 
118
        char *username;
 
119
        struct passwd *pw;
 
120
        NTSTATUS status;
 
121
 
 
122
        tmp_ctx = talloc_new(mem_ctx);
 
123
        if (!tmp_ctx) {
 
124
                return NT_STATUS_NO_MEMORY;
 
125
        }
 
126
 
 
127
        status = gse_get_pac_blob(gse_ctx, tmp_ctx, &pac);
 
128
        if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
 
129
                /* TODO: Fetch user by principal name ? */
 
130
                status = NT_STATUS_ACCESS_DENIED;
 
131
                goto done;
 
132
        }
 
133
        if (!NT_STATUS_IS_OK(status)) {
 
134
                goto done;
 
135
        }
 
136
 
 
137
        status = gse_get_client_name(gse_ctx, tmp_ctx, &princ_name);
 
138
        if (!NT_STATUS_IS_OK(status)) {
 
139
                goto done;
 
140
        }
 
141
 
 
142
        pac_data = talloc_zero(tmp_ctx, struct PAC_DATA);
 
143
        if (!pac_data) {
 
144
                status = NT_STATUS_NO_MEMORY;
 
145
                goto done;
 
146
        }
 
147
 
 
148
        ndr_err = ndr_pull_struct_blob(&pac, pac_data, pac_data,
 
149
                                (ndr_pull_flags_fn_t)ndr_pull_PAC_DATA);
 
150
        if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
 
151
                DEBUG(1, ("Failed to parse the PAC for %s\n", princ_name));
 
152
                status = ndr_map_error2ntstatus(ndr_err);
 
153
                goto done;
 
154
        }
 
155
 
 
156
        /* get logon name and logon info */
 
157
        for (i = 0; i < pac_data->num_buffers; i++) {
 
158
                struct PAC_BUFFER *data_buf = &pac_data->buffers[i];
 
159
 
 
160
                switch (data_buf->type) {
 
161
                case PAC_TYPE_LOGON_INFO:
 
162
                        if (!data_buf->info) {
 
163
                                break;
 
164
                        }
 
165
                        logon_info = data_buf->info->logon_info.info;
 
166
                        break;
 
167
                default:
 
168
                        break;
 
169
                }
 
170
        }
 
171
        if (!logon_info) {
 
172
                DEBUG(1, ("Invalid PAC data, missing logon info!\n"));
 
173
                status = NT_STATUS_NOT_FOUND;
 
174
                goto done;
 
175
        }
 
176
 
 
177
        /* TODO: Should we check princ_name against account_name in
 
178
         * logon_name ? Are they supposed to be identical, or can an
 
179
         * account_name be different from the UPN ? */
 
180
 
 
181
        status = get_user_from_kerberos_info(tmp_ctx, client_id->name,
 
182
                                             princ_name, logon_info,
 
183
                                             &is_mapped, &is_guest,
 
184
                                             &ntuser, &ntdomain,
 
185
                                             &username, &pw);
 
186
        if (!NT_STATUS_IS_OK(status)) {
 
187
                DEBUG(1, ("Failed to map kerberos principal to system user "
 
188
                          "(%s)\n", nt_errstr(status)));
 
189
                status = NT_STATUS_ACCESS_DENIED;
 
190
                goto done;
 
191
        }
 
192
 
 
193
        /* TODO: save PAC data in netsamlogon cache ? */
 
194
 
 
195
        status = make_server_info_krb5(mem_ctx,
 
196
                                        ntuser, ntdomain, username, pw,
 
197
                                        logon_info, is_guest, server_info);
 
198
        if (!NT_STATUS_IS_OK(status)) {
 
199
                DEBUG(1, ("Failed to map kerberos pac to server info (%s)\n",
 
200
                          nt_errstr(status)));
 
201
                status = NT_STATUS_ACCESS_DENIED;
 
202
                goto done;
 
203
        }
 
204
 
 
205
        DEBUG(5, (__location__ "OK: user: %s domain: %s client: %s\n",
 
206
                  ntuser, ntdomain, client_id->name));
 
207
 
 
208
        status = NT_STATUS_OK;
 
209
 
 
210
done:
 
211
        TALLOC_FREE(tmp_ctx);
 
212
        return status;
 
213
}