~lefteris-nikoltsios/+junk/samba-lp1016895

« back to all changes in this revision

Viewing changes to source4/dsdb/samdb/samdb.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:
23
23
 
24
24
#include "includes.h"
25
25
#include "librpc/gen_ndr/ndr_netlogon.h"
26
 
#include "librpc/gen_ndr/ndr_misc.h"
27
26
#include "librpc/gen_ndr/ndr_security.h"
28
27
#include "lib/events/events.h"
29
 
#include "lib/ldb/include/ldb.h"
30
 
#include "lib/ldb/include/ldb_errors.h"
 
28
#include "lib/ldb-samba/ldb_wrap.h"
 
29
#include <ldb.h>
 
30
#include <ldb_errors.h>
31
31
#include "libcli/security/security.h"
32
32
#include "libcli/auth/libcli_auth.h"
33
33
#include "libcli/ldap/ldap_ndr.h"
41
41
#include "lib/events/events.h"
42
42
#include "auth/credentials/credentials.h"
43
43
#include "param/secrets.h"
 
44
#include "auth/auth.h"
44
45
 
45
 
char *samdb_relative_path(struct ldb_context *ldb,
46
 
                                 TALLOC_CTX *mem_ctx, 
47
 
                                 const char *name) 
 
46
/*
 
47
  make sure the static credentials are not freed
 
48
 */
 
49
static int samdb_credentials_destructor(struct cli_credentials *creds)
48
50
{
49
 
        const char *base_url = 
50
 
                (const char *)ldb_get_opaque(ldb, "ldb_url");
51
 
        char *path, *p, *full_name;
52
 
        if (name == NULL) {
53
 
                return NULL;
54
 
        }
55
 
        if (name[0] == 0 || name[0] == '/' || strstr(name, ":/")) {
56
 
                return talloc_strdup(mem_ctx, name);
57
 
        }
58
 
        path = talloc_strdup(mem_ctx, base_url);
59
 
        if (path == NULL) {
60
 
                return NULL;
61
 
        }
62
 
        if ( (p = strrchr(path, '/')) != NULL) {
63
 
                p[0] = '\0';
64
 
                full_name = talloc_asprintf(mem_ctx, "%s/%s", path, name);
65
 
        } else {
66
 
                full_name = talloc_asprintf(mem_ctx, "./%s", name);
67
 
        }
68
 
        talloc_free(path);
69
 
        return full_name;
 
51
        return -1;
70
52
}
71
53
 
72
 
struct cli_credentials *samdb_credentials(TALLOC_CTX *mem_ctx, 
73
 
                                          struct tevent_context *event_ctx, 
74
 
                                          struct loadparm_context *lp_ctx) 
 
54
/*
 
55
  this returns a static set of system credentials. It is static so
 
56
  that we always get the same pointer in ldb_wrap_connect()
 
57
 */
 
58
struct cli_credentials *samdb_credentials(struct loadparm_context *lp_ctx)
75
59
{
76
 
        struct cli_credentials *cred = cli_credentials_init(mem_ctx);
 
60
        static struct cli_credentials *static_credentials;
 
61
        struct cli_credentials *cred;
 
62
        char *error_string;
 
63
 
 
64
        if (static_credentials) {
 
65
                return static_credentials;
 
66
        }
 
67
 
 
68
        cred = cli_credentials_init(talloc_autofree_context());
77
69
        if (!cred) {
78
70
                return NULL;
79
71
        }
84
76
         * anyway */
85
77
        cli_credentials_set_kerberos_state(cred, CRED_DONT_USE_KERBEROS);
86
78
 
87
 
        if (!NT_STATUS_IS_OK(cli_credentials_set_secrets(cred, event_ctx, lp_ctx, NULL, NULL,
88
 
                                                         SECRETS_LDAP_FILTER))) {
 
79
        if (!NT_STATUS_IS_OK(cli_credentials_set_secrets(cred, lp_ctx, NULL, NULL,
 
80
                                                         SECRETS_LDAP_FILTER, &error_string))) {
 
81
                DEBUG(5, ("(normal if no LDAP backend) %s", error_string));
89
82
                /* Perfectly OK - if not against an LDAP backend */
 
83
                talloc_free(cred);
90
84
                return NULL;
91
85
        }
 
86
        static_credentials = cred;
 
87
        talloc_set_destructor(cred, samdb_credentials_destructor);
92
88
        return cred;
93
89
}
94
90
 
99
95
struct ldb_context *samdb_connect(TALLOC_CTX *mem_ctx, 
100
96
                                  struct tevent_context *ev_ctx,
101
97
                                  struct loadparm_context *lp_ctx,
102
 
                                  struct auth_session_info *session_info)
 
98
                                  struct auth_session_info *session_info,
 
99
                                  int flags)
103
100
{
104
101
        struct ldb_context *ldb;
105
 
        ldb = ldb_wrap_connect(mem_ctx, ev_ctx, lp_ctx, 
106
 
                               lp_sam_url(lp_ctx), session_info,
107
 
                               samdb_credentials(mem_ctx, ev_ctx, lp_ctx), 
108
 
                               0, NULL);
109
 
        if (!ldb) {
110
 
                return NULL;
111
 
        }
112
 
        dsdb_make_schema_global(ldb);
 
102
        struct dsdb_schema *schema;
 
103
        const char *url;
 
104
        struct cli_credentials *credentials;
 
105
        int ret;
 
106
 
 
107
        url  = lpcfg_sam_url(lp_ctx);
 
108
        credentials = samdb_credentials(lp_ctx);
 
109
 
 
110
        ldb = ldb_wrap_find(url, ev_ctx, lp_ctx, session_info, credentials, flags);
 
111
        if (ldb != NULL)
 
112
                return talloc_reference(mem_ctx, ldb);
 
113
 
 
114
        ldb = samba_ldb_init(mem_ctx, ev_ctx, lp_ctx, session_info, credentials);
 
115
 
 
116
        if (ldb == NULL)
 
117
                return NULL;
 
118
 
 
119
        dsdb_set_global_schema(ldb);
 
120
 
 
121
        ret = samba_ldb_connect(ldb, lp_ctx, url, flags);
 
122
        if (ret != LDB_SUCCESS) {
 
123
                talloc_free(ldb);
 
124
                return NULL;
 
125
        }
 
126
 
 
127
        schema = dsdb_get_schema(ldb, NULL);
 
128
        /* make the resulting schema global */
 
129
        if (schema) {
 
130
                dsdb_make_schema_global(ldb, schema);
 
131
        }
 
132
 
 
133
        if (!ldb_wrap_add(url, ev_ctx, lp_ctx, session_info, credentials, flags, ldb)) {
 
134
                talloc_free(ldb);
 
135
                return NULL;
 
136
        }
 
137
 
113
138
        return ldb;
114
139
}
115
140
 
118
143
 Create the SID list for this user.
119
144
****************************************************************************/
120
145
NTSTATUS security_token_create(TALLOC_CTX *mem_ctx, 
121
 
                               struct tevent_context *ev_ctx, 
122
146
                               struct loadparm_context *lp_ctx,
123
 
                               struct dom_sid *user_sid,
124
 
                               struct dom_sid *group_sid, 
125
 
                               int n_groupSIDs,
126
 
                               struct dom_sid **groupSIDs, 
127
 
                               bool is_authenticated,
 
147
                               unsigned int num_sids,
 
148
                               struct dom_sid *sids,
 
149
                               uint32_t session_info_flags,
128
150
                               struct security_token **token)
129
151
{
130
152
        struct security_token *ptoken;
131
 
        int i;
 
153
        unsigned int i;
132
154
        NTSTATUS status;
133
155
 
134
156
        ptoken = security_token_initialise(mem_ctx);
135
157
        NT_STATUS_HAVE_NO_MEMORY(ptoken);
136
158
 
137
 
        ptoken->sids = talloc_array(ptoken, struct dom_sid *, n_groupSIDs + 5);
 
159
        ptoken->sids = talloc_array(ptoken, struct dom_sid, num_sids + 6 /* over-allocate */);
138
160
        NT_STATUS_HAVE_NO_MEMORY(ptoken->sids);
139
161
 
140
 
        ptoken->user_sid = talloc_reference(ptoken, user_sid);
141
 
        ptoken->group_sid = talloc_reference(ptoken, group_sid);
142
 
        ptoken->privilege_mask = 0;
143
 
 
144
 
        ptoken->sids[0] = ptoken->user_sid;
145
 
        ptoken->sids[1] = ptoken->group_sid;
146
 
 
147
 
        /*
148
 
         * Finally add the "standard" SIDs.
149
 
         * The only difference between guest and "anonymous"
150
 
         * is the addition of Authenticated_Users.
151
 
         */
152
 
        ptoken->sids[2] = dom_sid_parse_talloc(ptoken->sids, SID_WORLD);
153
 
        NT_STATUS_HAVE_NO_MEMORY(ptoken->sids[2]);
154
 
        ptoken->sids[3] = dom_sid_parse_talloc(ptoken->sids, SID_NT_NETWORK);
155
 
        NT_STATUS_HAVE_NO_MEMORY(ptoken->sids[3]);
156
 
        ptoken->num_sids = 4;
157
 
 
158
 
        if (is_authenticated) {
159
 
                ptoken->sids[4] = dom_sid_parse_talloc(ptoken->sids, SID_NT_AUTHENTICATED_USERS);
160
 
                NT_STATUS_HAVE_NO_MEMORY(ptoken->sids[4]);
161
 
                ptoken->num_sids++;
162
 
        }
163
 
 
164
 
        for (i = 0; i < n_groupSIDs; i++) {
 
162
        ptoken->num_sids = 0;
 
163
 
 
164
        for (i = 0; i < num_sids; i++) {
165
165
                size_t check_sid_idx;
166
 
                for (check_sid_idx = 1; 
167
 
                     check_sid_idx < ptoken->num_sids; 
 
166
                for (check_sid_idx = 0;
 
167
                     check_sid_idx < ptoken->num_sids;
168
168
                     check_sid_idx++) {
169
 
                        if (dom_sid_equal(ptoken->sids[check_sid_idx], groupSIDs[i])) {
 
169
                        if (dom_sid_equal(&ptoken->sids[check_sid_idx], &sids[i])) {
170
170
                                break;
171
171
                        }
172
172
                }
173
173
 
174
174
                if (check_sid_idx == ptoken->num_sids) {
175
 
                        ptoken->sids[ptoken->num_sids++] = talloc_reference(ptoken->sids, groupSIDs[i]);
176
 
                }
177
 
        }
178
 
 
179
 
        /* setup the privilege mask for this token */
180
 
        status = samdb_privilege_setup(ev_ctx, lp_ctx, ptoken);
181
 
        if (!NT_STATUS_IS_OK(status)) {
182
 
                talloc_free(ptoken);
183
 
                return status;
184
 
        }
185
 
 
186
 
        security_token_debug(10, ptoken);
 
175
                        ptoken->sids = talloc_realloc(ptoken, ptoken->sids, struct dom_sid, ptoken->num_sids + 1);
 
176
                        NT_STATUS_HAVE_NO_MEMORY(ptoken->sids);
 
177
 
 
178
                        ptoken->sids[ptoken->num_sids] = sids[i];
 
179
                        ptoken->num_sids++;
 
180
                }
 
181
        }
 
182
 
 
183
        /*
 
184
         * Finally add the "standard" sids.
 
185
         * The only difference between guest and "anonymous"
 
186
         * is the addition of Authenticated_Users.
 
187
         */
 
188
 
 
189
        if (session_info_flags & AUTH_SESSION_INFO_DEFAULT_GROUPS) {
 
190
                ptoken->sids = talloc_realloc(ptoken, ptoken->sids, struct dom_sid, ptoken->num_sids + 2);
 
191
                NT_STATUS_HAVE_NO_MEMORY(ptoken->sids);
 
192
 
 
193
                if (!dom_sid_parse(SID_WORLD, &ptoken->sids[ptoken->num_sids])) {
 
194
                        return NT_STATUS_INTERNAL_ERROR;
 
195
                }
 
196
                ptoken->num_sids++;
 
197
 
 
198
                if (!dom_sid_parse(SID_NT_NETWORK, &ptoken->sids[ptoken->num_sids])) {
 
199
                        return NT_STATUS_INTERNAL_ERROR;
 
200
                }
 
201
                ptoken->num_sids++;
 
202
        }
 
203
 
 
204
        if (session_info_flags & AUTH_SESSION_INFO_AUTHENTICATED) {
 
205
                ptoken->sids = talloc_realloc(ptoken, ptoken->sids, struct dom_sid, ptoken->num_sids + 1);
 
206
                NT_STATUS_HAVE_NO_MEMORY(ptoken->sids);
 
207
 
 
208
                if (!dom_sid_parse(SID_NT_AUTHENTICATED_USERS, &ptoken->sids[ptoken->num_sids])) {
 
209
                        return NT_STATUS_INTERNAL_ERROR;
 
210
                }
 
211
                ptoken->num_sids++;
 
212
        }
 
213
 
 
214
        /* The caller may have requested simple privilages, for example if there isn't a local DB */
 
215
        if (session_info_flags & AUTH_SESSION_INFO_SIMPLE_PRIVILEGES) {
 
216
                /* Shortcuts to prevent recursion and avoid lookups */
 
217
                if (ptoken->sids == NULL) {
 
218
                        ptoken->privilege_mask = 0;
 
219
                } else if (security_token_is_system(ptoken)) {
 
220
                        ptoken->privilege_mask = ~0;
 
221
                } else if (security_token_is_anonymous(ptoken)) {
 
222
                        ptoken->privilege_mask = 0;
 
223
                } else if (security_token_has_builtin_administrators(ptoken)) {
 
224
                        ptoken->privilege_mask = ~0;
 
225
                } else {
 
226
                        /* All other 'users' get a empty priv set so far */
 
227
                        ptoken->privilege_mask = 0;
 
228
                }
 
229
        } else {
 
230
                /* setup the privilege mask for this token */
 
231
                status = samdb_privilege_setup(lp_ctx, ptoken);
 
232
                if (!NT_STATUS_IS_OK(status)) {
 
233
                        talloc_free(ptoken);
 
234
                        DEBUG(1,("Unable to access privileges database\n"));
 
235
                        return status;
 
236
                }
 
237
        }
 
238
 
 
239
        security_token_debug(0, 10, ptoken);
187
240
 
188
241
        *token = ptoken;
189
242