Line data Source code
1 : /*
2 : Unix SMB/CIFS implementation.
3 :
4 : interface functions for the sam database
5 :
6 : Copyright (C) Andrew Tridgell 2004
7 : Copyright (C) Volker Lendecke 2004
8 : Copyright (C) Andrew Bartlett <abartlet@samba.org> 2006
9 :
10 : This program is free software; you can redistribute it and/or modify
11 : it under the terms of the GNU General Public License as published by
12 : the Free Software Foundation; either version 3 of the License, or
13 : (at your option) any later version.
14 :
15 : This program is distributed in the hope that it will be useful,
16 : but WITHOUT ANY WARRANTY; without even the implied warranty of
17 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 : GNU General Public License for more details.
19 :
20 : You should have received a copy of the GNU General Public License
21 : along with this program. If not, see <http://www.gnu.org/licenses/>.
22 : */
23 :
24 : #include "includes.h"
25 : #include "librpc/gen_ndr/ndr_netlogon.h"
26 : #include "librpc/gen_ndr/ndr_security.h"
27 : #include "lib/events/events.h"
28 : #include "lib/ldb-samba/ldb_wrap.h"
29 : #include <ldb.h>
30 : #include <ldb_errors.h>
31 : #include "libcli/security/security.h"
32 : #include "libcli/auth/libcli_auth.h"
33 : #include "libcli/ldap/ldap_ndr.h"
34 : #include "system/time.h"
35 : #include "system/filesys.h"
36 : #include "ldb_wrap.h"
37 : #include "../lib/util/util_ldb.h"
38 : #include "dsdb/samdb/samdb.h"
39 : #include "../libds/common/flags.h"
40 : #include "param/param.h"
41 : #include "lib/events/events.h"
42 : #include "auth/credentials/credentials.h"
43 : #include "param/secrets.h"
44 : #include "auth/auth.h"
45 : #include "lib/tsocket/tsocket.h"
46 :
47 : /*
48 : connect to the SAM database specified by URL
49 : return an opaque context pointer on success, or NULL on failure
50 : */
51 158319 : int samdb_connect_url(TALLOC_CTX *mem_ctx,
52 : struct tevent_context *ev_ctx,
53 : struct loadparm_context *lp_ctx,
54 : struct auth_session_info *session_info,
55 : unsigned int flags,
56 : const char *url,
57 : const struct tsocket_address *remote_address,
58 : struct ldb_context **ldb_ret,
59 : char **errstring)
60 : {
61 158319 : struct ldb_context *ldb = NULL;
62 : int ret;
63 158319 : *ldb_ret = NULL;
64 158319 : *errstring = NULL;
65 :
66 : /* We create sam.ldb in provision, and never anywhere else */
67 158319 : flags |= LDB_FLG_DONT_CREATE_DB;
68 :
69 158319 : if (remote_address == NULL) {
70 105733 : ldb = ldb_wrap_find(url, ev_ctx, lp_ctx,
71 : session_info, NULL, flags);
72 105733 : if (ldb != NULL) {
73 53940 : *ldb_ret = talloc_reference(mem_ctx, ldb);
74 53940 : if (*ldb_ret == NULL) {
75 0 : return LDB_ERR_OPERATIONS_ERROR;
76 : }
77 53940 : return LDB_SUCCESS;
78 : }
79 : }
80 :
81 104379 : ldb = samba_ldb_init(mem_ctx, ev_ctx, lp_ctx, session_info, NULL);
82 :
83 104379 : if (ldb == NULL) {
84 0 : *errstring = talloc_asprintf(mem_ctx,
85 : "Failed to set up Samba ldb "
86 : "wrappers with samba_ldb_init() "
87 : "to connect to %s",
88 : url);
89 0 : return LDB_ERR_OPERATIONS_ERROR;
90 : }
91 :
92 104379 : dsdb_set_global_schema(ldb);
93 :
94 104379 : ret = samba_ldb_connect(ldb, lp_ctx, url, flags);
95 104379 : if (ret != LDB_SUCCESS) {
96 4 : *errstring = talloc_asprintf(mem_ctx,
97 : "Failed to connect to %s: %s",
98 : url,
99 : ldb_errstring(ldb));
100 4 : talloc_free(ldb);
101 4 : return LDB_ERR_OPERATIONS_ERROR;
102 : }
103 :
104 : /*
105 : * If a remote_address was specified, then set it on the DB
106 : * and do not add to the wrap list (as we need to keep the LDB
107 : * pointer unique for the address).
108 : *
109 : * We use this for audit logging and for the "netlogon" attribute
110 : */
111 104375 : if (remote_address != NULL) {
112 52586 : ldb_set_opaque(ldb, "remoteAddress",
113 : discard_const(remote_address));
114 52586 : *ldb_ret = ldb;
115 52586 : return LDB_SUCCESS;
116 : }
117 :
118 51789 : if (!ldb_wrap_add(url, ev_ctx, lp_ctx, session_info, NULL, flags, ldb)) {
119 0 : *errstring = talloc_asprintf(mem_ctx,
120 : "Failed to add cached DB reference"
121 : " to %s",
122 : url);
123 0 : talloc_free(ldb);
124 0 : return LDB_ERR_OPERATIONS_ERROR;
125 : }
126 :
127 51789 : *ldb_ret = ldb;
128 51789 : return LDB_SUCCESS;
129 : }
130 :
131 :
132 : /*
133 : connect to the SAM database
134 : return an opaque context pointer on success, or NULL on failure
135 : */
136 115432 : struct ldb_context *samdb_connect(TALLOC_CTX *mem_ctx,
137 : struct tevent_context *ev_ctx,
138 : struct loadparm_context *lp_ctx,
139 : struct auth_session_info *session_info,
140 : const struct tsocket_address *remote_address,
141 : unsigned int flags)
142 : {
143 : char *errstring;
144 : struct ldb_context *ldb;
145 115432 : int ret = samdb_connect_url(mem_ctx,
146 : ev_ctx,
147 : lp_ctx,
148 : session_info,
149 : flags,
150 : "sam.ldb",
151 : remote_address,
152 : &ldb,
153 : &errstring);
154 115432 : if (ret == LDB_SUCCESS) {
155 115428 : return ldb;
156 : }
157 4 : return NULL;
158 : }
159 :
160 : /****************************************************************************
161 : Create the SID list for this user.
162 : ****************************************************************************/
163 69408 : NTSTATUS security_token_create(TALLOC_CTX *mem_ctx,
164 : struct loadparm_context *lp_ctx,
165 : unsigned int num_sids,
166 : struct dom_sid *sids,
167 : uint32_t session_info_flags,
168 : struct security_token **token)
169 : {
170 : struct security_token *ptoken;
171 : unsigned int i;
172 : NTSTATUS status;
173 :
174 69408 : ptoken = security_token_initialise(mem_ctx);
175 69408 : NT_STATUS_HAVE_NO_MEMORY(ptoken);
176 :
177 69408 : ptoken->sids = talloc_array(ptoken, struct dom_sid, num_sids + 6 /* over-allocate */);
178 69408 : NT_STATUS_HAVE_NO_MEMORY(ptoken->sids);
179 :
180 69408 : ptoken->num_sids = 0;
181 :
182 512317 : for (i = 0; i < num_sids; i++) {
183 : size_t check_sid_idx;
184 2774539 : for (check_sid_idx = 0;
185 2943918 : check_sid_idx < ptoken->num_sids;
186 2501009 : check_sid_idx++) {
187 2501009 : if (dom_sid_equal(&ptoken->sids[check_sid_idx], &sids[i])) {
188 0 : break;
189 : }
190 : }
191 :
192 442909 : if (check_sid_idx == ptoken->num_sids) {
193 442909 : ptoken->sids = talloc_realloc(ptoken, ptoken->sids, struct dom_sid, ptoken->num_sids + 1);
194 442909 : NT_STATUS_HAVE_NO_MEMORY(ptoken->sids);
195 :
196 442909 : ptoken->sids[ptoken->num_sids] = sids[i];
197 442909 : ptoken->num_sids++;
198 : }
199 : }
200 :
201 : /* The caller may have requested simple privilages, for example if there isn't a local DB */
202 69408 : if (session_info_flags & AUTH_SESSION_INFO_SIMPLE_PRIVILEGES) {
203 : /* Shortcuts to prevent recursion and avoid lookups */
204 38321 : if (ptoken->sids == NULL) {
205 0 : ptoken->privilege_mask = 0;
206 38321 : } else if (security_token_is_system(ptoken)) {
207 4410 : ptoken->privilege_mask = ~0;
208 33911 : } else if (security_token_is_anonymous(ptoken)) {
209 32211 : ptoken->privilege_mask = 0;
210 1700 : } else if (security_token_has_builtin_administrators(ptoken)) {
211 452 : ptoken->privilege_mask = ~0;
212 : } else {
213 : /* All other 'users' get a empty priv set so far */
214 1248 : ptoken->privilege_mask = 0;
215 : }
216 : } else {
217 : /* setup the privilege mask for this token */
218 31087 : status = samdb_privilege_setup(lp_ctx, ptoken);
219 31087 : if (!NT_STATUS_IS_OK(status)) {
220 0 : talloc_free(ptoken);
221 0 : DEBUG(1,("Unable to access privileges database\n"));
222 0 : return status;
223 : }
224 : }
225 :
226 69408 : security_token_debug(0, 10, ptoken);
227 :
228 69408 : *token = ptoken;
229 :
230 69408 : return NT_STATUS_OK;
231 : }
|