Line data Source code
1 : /*
2 : Unix SMB/CIFS implementation.
3 : LDAP protocol helper functions for SAMBA
4 : Copyright (C) Jean François Micouleau 1998
5 : Copyright (C) Gerald Carter 2001-2003
6 : Copyright (C) Shahms King 2001
7 : Copyright (C) Andrew Bartlett 2002-2003
8 : Copyright (C) Stefan (metze) Metzmacher 2002-2003
9 : Copyright (C) Simo Sorce 2006
10 :
11 : This program is free software; you can redistribute it and/or modify
12 : it under the terms of the GNU General Public License as published by
13 : the Free Software Foundation; either version 3 of the License, or
14 : (at your option) any later version.
15 :
16 : This program is distributed in the hope that it will be useful,
17 : but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : GNU General Public License for more details.
20 :
21 : You should have received a copy of the GNU General Public License
22 : along with this program. If not, see <http://www.gnu.org/licenses/>.
23 :
24 : */
25 :
26 : /* TODO:
27 : * persistent connections: if using NSS LDAP, many connections are made
28 : * however, using only one within Samba would be nice
29 : *
30 : * Clean up SSL stuff, compile on OpenLDAP 1.x, 2.x, and Netscape SDK
31 : *
32 : * Other LDAP based login attributes: accountExpires, etc.
33 : * (should be the domain of Samba proper, but the sam_password/struct samu
34 : * structures don't have fields for some of these attributes)
35 : *
36 : * SSL is done, but can't get the certificate based authentication to work
37 : * against on my test platform (Linux 2.4, OpenLDAP 2.x)
38 : */
39 :
40 : /* NOTE: this will NOT work against an Active Directory server
41 : * due to the fact that the two password fields cannot be retrieved
42 : * from a server; recommend using security = domain in this situation
43 : * and/or winbind
44 : */
45 :
46 : #include "includes.h"
47 : #include "passdb.h"
48 : #include "../libcli/auth/libcli_auth.h"
49 : #include "secrets.h"
50 : #include "idmap_cache.h"
51 : #include "../libcli/security/security.h"
52 : #include "../lib/util/util_pw.h"
53 : #include "lib/winbind_util.h"
54 : #include "librpc/gen_ndr/idmap.h"
55 : #include "lib/param/loadparm.h"
56 : #include "lib/util_sid_passdb.h"
57 : #include "lib/util/smb_strtox.h"
58 : #include "lib/util/string_wrappers.h"
59 : #include "source3/lib/substitute.h"
60 :
61 : #undef DBGC_CLASS
62 : #define DBGC_CLASS DBGC_PASSDB
63 :
64 : #include <lber.h>
65 : #include <ldap.h>
66 :
67 :
68 : #include "smbldap.h"
69 : #include "passdb/pdb_ldap.h"
70 : #include "passdb/pdb_nds.h"
71 : #include "passdb/pdb_ldap_util.h"
72 : #include "passdb/pdb_ldap_schema.h"
73 :
74 : /**********************************************************************
75 : Simple helper function to make stuff better readable
76 : **********************************************************************/
77 :
78 0 : LDAP *priv2ld(struct ldapsam_privates *priv)
79 : {
80 0 : return smbldap_get_ldap(priv->smbldap_state);
81 : }
82 :
83 : /**********************************************************************
84 : Get the attribute name given a user schema version.
85 : **********************************************************************/
86 :
87 0 : static const char* get_userattr_key2string( int schema_ver, int key )
88 : {
89 0 : switch ( schema_ver ) {
90 0 : case SCHEMAVER_SAMBASAMACCOUNT:
91 0 : return get_attr_key2string( attrib_map_v30, key );
92 :
93 0 : default:
94 0 : DEBUG(0,("get_userattr_key2string: unknown schema version specified\n"));
95 0 : break;
96 : }
97 0 : return NULL;
98 : }
99 :
100 : /**********************************************************************
101 : Return the list of attribute names given a user schema version.
102 : **********************************************************************/
103 :
104 0 : const char** get_userattr_list( TALLOC_CTX *mem_ctx, int schema_ver )
105 : {
106 0 : switch ( schema_ver ) {
107 0 : case SCHEMAVER_SAMBASAMACCOUNT:
108 0 : return get_attr_list( mem_ctx, attrib_map_v30 );
109 0 : default:
110 0 : DEBUG(0,("get_userattr_list: unknown schema version specified!\n"));
111 0 : break;
112 : }
113 :
114 0 : return NULL;
115 : }
116 :
117 : /**************************************************************************
118 : Return the list of attribute names to delete given a user schema version.
119 : **************************************************************************/
120 :
121 0 : static const char** get_userattr_delete_list( TALLOC_CTX *mem_ctx,
122 : int schema_ver )
123 : {
124 0 : switch ( schema_ver ) {
125 0 : case SCHEMAVER_SAMBASAMACCOUNT:
126 0 : return get_attr_list( mem_ctx,
127 : attrib_map_to_delete_v30 );
128 0 : default:
129 0 : DEBUG(0,("get_userattr_delete_list: unknown schema version specified!\n"));
130 0 : break;
131 : }
132 :
133 0 : return NULL;
134 : }
135 :
136 :
137 : /*******************************************************************
138 : Generate the LDAP search filter for the objectclass based on the
139 : version of the schema we are using.
140 : ******************************************************************/
141 :
142 0 : static const char* get_objclass_filter( int schema_ver )
143 : {
144 0 : fstring objclass_filter;
145 0 : char *result;
146 :
147 0 : switch( schema_ver ) {
148 0 : case SCHEMAVER_SAMBASAMACCOUNT:
149 0 : fstr_sprintf( objclass_filter, "(objectclass=%s)", LDAP_OBJ_SAMBASAMACCOUNT );
150 0 : break;
151 0 : default:
152 0 : DEBUG(0,("get_objclass_filter: Invalid schema version specified!\n"));
153 0 : objclass_filter[0] = '\0';
154 0 : break;
155 : }
156 :
157 0 : result = talloc_strdup(talloc_tos(), objclass_filter);
158 0 : SMB_ASSERT(result != NULL);
159 0 : return result;
160 : }
161 :
162 : /*****************************************************************
163 : Scan a sequence number off OpenLDAP's syncrepl contextCSN
164 : ******************************************************************/
165 :
166 0 : static NTSTATUS ldapsam_get_seq_num(struct pdb_methods *my_methods, time_t *seq_num)
167 : {
168 0 : struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
169 0 : NTSTATUS ntstatus = NT_STATUS_UNSUCCESSFUL;
170 0 : LDAPMessage *msg = NULL;
171 0 : LDAPMessage *entry = NULL;
172 0 : TALLOC_CTX *mem_ctx;
173 0 : char **values = NULL;
174 0 : int rc, num_result, num_values, rid;
175 0 : char *suffix = NULL;
176 0 : char *tok;
177 0 : const char *p;
178 0 : const char **attrs;
179 :
180 : /* Unfortunately there is no proper way to detect syncrepl-support in
181 : * smbldap_connect_system(). The syncrepl OIDs are submitted for publication
182 : * but do not show up in the root-DSE yet. Neither we can query the
183 : * subschema-context for the syncProviderSubentry or syncConsumerSubentry
184 : * objectclass. Currently we require lp_ldap_suffix() to show up as
185 : * namingContext. - Guenther
186 : */
187 :
188 0 : if (!lp_parm_bool(-1, "ldapsam", "syncrepl_seqnum", False)) {
189 0 : return ntstatus;
190 : }
191 :
192 0 : if (!seq_num) {
193 0 : DEBUG(3,("ldapsam_get_seq_num: no sequence_number\n"));
194 0 : return ntstatus;
195 : }
196 :
197 0 : if (!smbldap_has_naming_context(
198 : smbldap_get_ldap(ldap_state->smbldap_state),
199 : lp_ldap_suffix())) {
200 0 : DEBUG(3,("ldapsam_get_seq_num: DIT not configured to hold %s "
201 : "as top-level namingContext\n", lp_ldap_suffix()));
202 0 : return ntstatus;
203 : }
204 :
205 0 : mem_ctx = talloc_init("ldapsam_get_seq_num");
206 :
207 0 : if (mem_ctx == NULL)
208 0 : return NT_STATUS_NO_MEMORY;
209 :
210 0 : if ((attrs = talloc_array(mem_ctx, const char *, 2)) == NULL) {
211 0 : ntstatus = NT_STATUS_NO_MEMORY;
212 0 : goto done;
213 : }
214 :
215 : /* if we got a syncrepl-rid (up to three digits long) we speak with a consumer */
216 0 : rid = lp_parm_int(-1, "ldapsam", "syncrepl_rid", -1);
217 0 : if (rid > 0) {
218 :
219 : /* consumer syncreplCookie: */
220 : /* csn=20050126161620Z#0000001#00#00000 */
221 0 : attrs[0] = talloc_strdup(mem_ctx, "syncreplCookie");
222 0 : attrs[1] = NULL;
223 0 : suffix = talloc_asprintf(mem_ctx,
224 : "cn=syncrepl%d,%s", rid, lp_ldap_suffix());
225 0 : if (!suffix) {
226 0 : ntstatus = NT_STATUS_NO_MEMORY;
227 0 : goto done;
228 : }
229 : } else {
230 :
231 : /* provider contextCSN */
232 : /* 20050126161620Z#000009#00#000000 */
233 0 : attrs[0] = talloc_strdup(mem_ctx, "contextCSN");
234 0 : attrs[1] = NULL;
235 0 : suffix = talloc_asprintf(mem_ctx,
236 : "cn=ldapsync,%s", lp_ldap_suffix());
237 :
238 0 : if (!suffix) {
239 0 : ntstatus = NT_STATUS_NO_MEMORY;
240 0 : goto done;
241 : }
242 : }
243 :
244 0 : rc = smbldap_search(ldap_state->smbldap_state, suffix,
245 : LDAP_SCOPE_BASE, "(objectclass=*)", attrs, 0, &msg);
246 :
247 0 : if (rc != LDAP_SUCCESS) {
248 0 : goto done;
249 : }
250 :
251 0 : num_result = ldap_count_entries(
252 : smbldap_get_ldap(ldap_state->smbldap_state), msg);
253 0 : if (num_result != 1) {
254 0 : DEBUG(3,("ldapsam_get_seq_num: Expected one entry, got %d\n", num_result));
255 0 : goto done;
256 : }
257 :
258 0 : entry = ldap_first_entry(
259 : smbldap_get_ldap(ldap_state->smbldap_state), msg);
260 0 : if (entry == NULL) {
261 0 : DEBUG(3,("ldapsam_get_seq_num: Could not retrieve entry\n"));
262 0 : goto done;
263 : }
264 :
265 0 : values = ldap_get_values(
266 : smbldap_get_ldap(ldap_state->smbldap_state), entry, attrs[0]);
267 0 : if (values == NULL) {
268 0 : DEBUG(3,("ldapsam_get_seq_num: no values\n"));
269 0 : goto done;
270 : }
271 :
272 0 : num_values = ldap_count_values(values);
273 0 : if (num_values == 0) {
274 0 : DEBUG(3,("ldapsam_get_seq_num: not a single value\n"));
275 0 : goto done;
276 : }
277 :
278 0 : p = values[0];
279 0 : if (!next_token_talloc(mem_ctx, &p, &tok, "#")) {
280 0 : DEBUG(0,("ldapsam_get_seq_num: failed to parse sequence number\n"));
281 0 : goto done;
282 : }
283 :
284 0 : p = tok;
285 0 : if (!strncmp(p, "csn=", strlen("csn=")))
286 0 : p += strlen("csn=");
287 :
288 0 : DEBUG(10,("ldapsam_get_seq_num: got %s: %s\n", attrs[0], p));
289 :
290 0 : *seq_num = generalized_to_unix_time(p);
291 :
292 : /* very basic sanity check */
293 0 : if (*seq_num <= 0) {
294 0 : DEBUG(3,("ldapsam_get_seq_num: invalid sequence number: %d\n",
295 : (int)*seq_num));
296 0 : goto done;
297 : }
298 :
299 0 : ntstatus = NT_STATUS_OK;
300 :
301 0 : done:
302 0 : if (values != NULL)
303 0 : ldap_value_free(values);
304 0 : if (msg != NULL)
305 0 : ldap_msgfree(msg);
306 0 : if (mem_ctx)
307 0 : talloc_destroy(mem_ctx);
308 :
309 0 : return ntstatus;
310 : }
311 :
312 : /*******************************************************************
313 : Run the search by name.
314 : ******************************************************************/
315 :
316 0 : int ldapsam_search_suffix_by_name(struct ldapsam_privates *ldap_state,
317 : const char *user,
318 : LDAPMessage ** result,
319 : const char **attr)
320 : {
321 0 : char *filter = NULL;
322 0 : char *escape_user = escape_ldap_string(talloc_tos(), user);
323 0 : int ret = -1;
324 :
325 0 : if (!escape_user) {
326 0 : return LDAP_NO_MEMORY;
327 : }
328 :
329 : /*
330 : * in the filter expression, replace %u with the real name
331 : * so in ldap filter, %u MUST exist :-)
332 : */
333 0 : filter = talloc_asprintf(talloc_tos(), "(&%s%s)", "(uid=%u)",
334 : get_objclass_filter(ldap_state->schema_ver));
335 0 : if (!filter) {
336 0 : TALLOC_FREE(escape_user);
337 0 : return LDAP_NO_MEMORY;
338 : }
339 : /*
340 : * have to use this here because $ is filtered out
341 : * in string_sub
342 : */
343 :
344 0 : filter = talloc_all_string_sub(talloc_tos(),
345 : filter, "%u", escape_user);
346 0 : TALLOC_FREE(escape_user);
347 0 : if (!filter) {
348 0 : return LDAP_NO_MEMORY;
349 : }
350 :
351 0 : ret = smbldap_search_suffix(ldap_state->smbldap_state,
352 : filter, attr, result);
353 0 : TALLOC_FREE(filter);
354 0 : return ret;
355 : }
356 :
357 : /*******************************************************************
358 : Run the search by SID.
359 : ******************************************************************/
360 :
361 0 : static int ldapsam_search_suffix_by_sid (struct ldapsam_privates *ldap_state,
362 : const struct dom_sid *sid, LDAPMessage ** result,
363 : const char **attr)
364 : {
365 0 : char *filter = NULL;
366 0 : int rc;
367 0 : struct dom_sid_buf sid_string;
368 :
369 0 : filter = talloc_asprintf(talloc_tos(), "(&(%s=%s)%s)",
370 : get_userattr_key2string(ldap_state->schema_ver,
371 : LDAP_ATTR_USER_SID),
372 : dom_sid_str_buf(sid, &sid_string),
373 : get_objclass_filter(ldap_state->schema_ver));
374 0 : if (!filter) {
375 0 : return LDAP_NO_MEMORY;
376 : }
377 :
378 0 : rc = smbldap_search_suffix(ldap_state->smbldap_state,
379 : filter, attr, result);
380 :
381 0 : TALLOC_FREE(filter);
382 0 : return rc;
383 : }
384 :
385 : /*******************************************************************
386 : Delete complete object or objectclass and attrs from
387 : object found in search_result depending on lp_ldap_delete_dn
388 : ******************************************************************/
389 :
390 0 : static int ldapsam_delete_entry(struct ldapsam_privates *priv,
391 : TALLOC_CTX *mem_ctx,
392 : LDAPMessage *entry,
393 : const char *objectclass,
394 : const char **attrs)
395 : {
396 0 : LDAPMod **mods = NULL;
397 0 : char *name;
398 0 : const char *dn;
399 0 : BerElement *ptr = NULL;
400 :
401 0 : dn = smbldap_talloc_dn(mem_ctx, priv2ld(priv), entry);
402 0 : if (dn == NULL) {
403 0 : return LDAP_NO_MEMORY;
404 : }
405 :
406 0 : if (lp_ldap_delete_dn()) {
407 0 : return smbldap_delete(priv->smbldap_state, dn);
408 : }
409 :
410 : /* Ok, delete only the SAM attributes */
411 :
412 0 : for (name = ldap_first_attribute(priv2ld(priv), entry, &ptr);
413 0 : name != NULL;
414 0 : name = ldap_next_attribute(priv2ld(priv), entry, ptr)) {
415 : const char **attrib;
416 :
417 : /* We are only allowed to delete the attributes that
418 : really exist. */
419 :
420 0 : for (attrib = attrs; *attrib != NULL; attrib++) {
421 0 : if (strequal(*attrib, name)) {
422 0 : DEBUG(10, ("ldapsam_delete_entry: deleting "
423 : "attribute %s\n", name));
424 0 : smbldap_set_mod(&mods, LDAP_MOD_DELETE, name,
425 : NULL);
426 : }
427 : }
428 0 : ldap_memfree(name);
429 : }
430 :
431 0 : if (ptr != NULL) {
432 0 : ber_free(ptr, 0);
433 : }
434 :
435 0 : smbldap_set_mod(&mods, LDAP_MOD_DELETE, "objectClass", objectclass);
436 0 : smbldap_talloc_autofree_ldapmod(mem_ctx, mods);
437 :
438 0 : return smbldap_modify(priv->smbldap_state, dn, mods);
439 : }
440 :
441 0 : static time_t ldapsam_get_entry_timestamp( struct ldapsam_privates *ldap_state, LDAPMessage * entry)
442 : {
443 0 : char *temp;
444 0 : struct tm tm = {};
445 :
446 0 : temp = smbldap_talloc_single_attribute(
447 : smbldap_get_ldap(ldap_state->smbldap_state), entry,
448 : get_userattr_key2string(ldap_state->schema_ver,
449 : LDAP_ATTR_MOD_TIMESTAMP),
450 : talloc_tos());
451 0 : if (!temp) {
452 0 : return (time_t) 0;
453 : }
454 :
455 0 : if ( !strptime(temp, "%Y%m%d%H%M%SZ", &tm)) {
456 0 : DEBUG(2,("ldapsam_get_entry_timestamp: strptime failed on: %s\n",
457 : (char*)temp));
458 0 : TALLOC_FREE(temp);
459 0 : return (time_t) 0;
460 : }
461 0 : TALLOC_FREE(temp);
462 0 : tzset();
463 0 : return timegm(&tm);
464 : }
465 :
466 : /**********************************************************************
467 : Initialize struct samu from an LDAP query.
468 : (Based on init_sam_from_buffer in pdb_tdb.c)
469 : *********************************************************************/
470 :
471 0 : static bool init_sam_from_ldap(struct ldapsam_privates *ldap_state,
472 : struct samu * sampass,
473 : LDAPMessage * entry)
474 : {
475 0 : time_t logon_time,
476 : logoff_time,
477 : kickoff_time,
478 : pass_last_set_time,
479 : pass_can_change_time,
480 : ldap_entry_time,
481 : bad_password_time;
482 0 : char *username = NULL,
483 0 : *domain = NULL,
484 0 : *nt_username = NULL,
485 0 : *fullname = NULL,
486 0 : *homedir = NULL,
487 0 : *dir_drive = NULL,
488 0 : *logon_script = NULL,
489 0 : *profile_path = NULL,
490 0 : *acct_desc = NULL,
491 0 : *workstations = NULL,
492 0 : *munged_dial = NULL;
493 0 : uint32_t user_rid;
494 0 : uint8_t smblmpwd[LM_HASH_LEN],
495 : smbntpwd[NT_HASH_LEN];
496 0 : bool use_samba_attrs = True;
497 0 : uint16_t logon_divs;
498 0 : uint16_t bad_password_count = 0,
499 0 : logon_count = 0;
500 0 : uint32_t hours_len;
501 0 : uint8_t hours[MAX_HOURS_LEN];
502 0 : char *temp = NULL;
503 0 : struct login_cache cache_entry;
504 0 : uint32_t pwHistLen;
505 0 : bool expand_explicit = lp_passdb_expand_explicit();
506 0 : bool ret = false;
507 0 : TALLOC_CTX *ctx = talloc_init("init_sam_from_ldap");
508 :
509 0 : if (!ctx) {
510 0 : return false;
511 : }
512 0 : if (sampass == NULL || ldap_state == NULL || entry == NULL) {
513 0 : DEBUG(0, ("init_sam_from_ldap: NULL parameters found!\n"));
514 0 : goto fn_exit;
515 : }
516 :
517 0 : if (priv2ld(ldap_state) == NULL) {
518 0 : DEBUG(0, ("init_sam_from_ldap: ldap_state->smbldap_state->"
519 : "ldap_struct is NULL!\n"));
520 0 : goto fn_exit;
521 : }
522 :
523 0 : if (!(username = smbldap_talloc_first_attribute(priv2ld(ldap_state),
524 : entry,
525 : "uid",
526 : ctx))) {
527 0 : DEBUG(1, ("init_sam_from_ldap: No uid attribute found for "
528 : "this user!\n"));
529 0 : goto fn_exit;
530 : }
531 :
532 0 : DEBUG(2, ("init_sam_from_ldap: Entry found for user: %s\n", username));
533 :
534 0 : nt_username = talloc_strdup(ctx, username);
535 0 : if (!nt_username) {
536 0 : goto fn_exit;
537 : }
538 :
539 0 : domain = talloc_strdup(ctx, ldap_state->domain_name);
540 0 : if (!domain) {
541 0 : goto fn_exit;
542 : }
543 :
544 0 : pdb_set_username(sampass, username, PDB_SET);
545 :
546 0 : pdb_set_domain(sampass, domain, PDB_DEFAULT);
547 0 : pdb_set_nt_username(sampass, nt_username, PDB_SET);
548 :
549 : /* deal with different attributes between the schema first */
550 :
551 0 : if ( ldap_state->schema_ver == SCHEMAVER_SAMBASAMACCOUNT ) {
552 0 : if ((temp = smbldap_talloc_single_attribute(
553 : smbldap_get_ldap(ldap_state->smbldap_state),
554 : entry,
555 : get_userattr_key2string(ldap_state->schema_ver,
556 : LDAP_ATTR_USER_SID),
557 : ctx))!=NULL) {
558 0 : pdb_set_user_sid_from_string(sampass, temp, PDB_SET);
559 : }
560 : } else {
561 0 : if ((temp = smbldap_talloc_single_attribute(
562 : smbldap_get_ldap(ldap_state->smbldap_state),
563 : entry,
564 : get_userattr_key2string(ldap_state->schema_ver,
565 : LDAP_ATTR_USER_RID),
566 : ctx))!=NULL) {
567 0 : user_rid = (uint32_t)atol(temp);
568 0 : pdb_set_user_sid_from_rid(sampass, user_rid, PDB_SET);
569 : }
570 : }
571 :
572 0 : if (IS_SAM_DEFAULT(sampass, PDB_USERSID)) {
573 0 : DEBUG(1, ("init_sam_from_ldap: no %s or %s attribute found for this user %s\n",
574 : get_userattr_key2string(ldap_state->schema_ver,
575 : LDAP_ATTR_USER_SID),
576 : get_userattr_key2string(ldap_state->schema_ver,
577 : LDAP_ATTR_USER_RID),
578 : username));
579 0 : return False;
580 : }
581 :
582 0 : temp = smbldap_talloc_single_attribute(
583 : smbldap_get_ldap(ldap_state->smbldap_state),
584 : entry,
585 : get_userattr_key2string(ldap_state->schema_ver,
586 : LDAP_ATTR_PWD_LAST_SET),
587 : ctx);
588 0 : if (temp) {
589 0 : pass_last_set_time = (time_t) atol(temp);
590 0 : pdb_set_pass_last_set_time(sampass,
591 : pass_last_set_time, PDB_SET);
592 : }
593 :
594 0 : temp = smbldap_talloc_single_attribute(
595 : smbldap_get_ldap(ldap_state->smbldap_state),
596 : entry,
597 : get_userattr_key2string(ldap_state->schema_ver,
598 : LDAP_ATTR_LOGON_TIME),
599 : ctx);
600 0 : if (temp) {
601 0 : logon_time = (time_t) atol(temp);
602 0 : pdb_set_logon_time(sampass, logon_time, PDB_SET);
603 : }
604 :
605 0 : temp = smbldap_talloc_single_attribute(
606 : smbldap_get_ldap(ldap_state->smbldap_state),
607 : entry,
608 : get_userattr_key2string(ldap_state->schema_ver,
609 : LDAP_ATTR_LOGOFF_TIME),
610 : ctx);
611 0 : if (temp) {
612 0 : logoff_time = (time_t) atol(temp);
613 0 : pdb_set_logoff_time(sampass, logoff_time, PDB_SET);
614 : }
615 :
616 0 : temp = smbldap_talloc_single_attribute(
617 : smbldap_get_ldap(ldap_state->smbldap_state),
618 : entry,
619 : get_userattr_key2string(ldap_state->schema_ver,
620 : LDAP_ATTR_KICKOFF_TIME),
621 : ctx);
622 0 : if (temp) {
623 0 : kickoff_time = (time_t) atol(temp);
624 0 : pdb_set_kickoff_time(sampass, kickoff_time, PDB_SET);
625 : }
626 :
627 0 : temp = smbldap_talloc_single_attribute(
628 : smbldap_get_ldap(ldap_state->smbldap_state),
629 : entry,
630 : get_userattr_key2string(ldap_state->schema_ver,
631 : LDAP_ATTR_PWD_CAN_CHANGE),
632 : ctx);
633 0 : if (temp) {
634 0 : pass_can_change_time = (time_t) atol(temp);
635 0 : pdb_set_pass_can_change_time(sampass,
636 : pass_can_change_time, PDB_SET);
637 : }
638 :
639 : /* recommend that 'gecos' and 'displayName' should refer to the same
640 : * attribute OID. userFullName depreciated, only used by Samba
641 : * primary rules of LDAP: don't make a new attribute when one is already defined
642 : * that fits your needs; using cn then displayName rather than 'userFullName'
643 : */
644 :
645 0 : fullname = smbldap_talloc_single_attribute(
646 : smbldap_get_ldap(ldap_state->smbldap_state),
647 : entry,
648 : get_userattr_key2string(ldap_state->schema_ver,
649 : LDAP_ATTR_DISPLAY_NAME),
650 : ctx);
651 0 : if (fullname) {
652 0 : pdb_set_fullname(sampass, fullname, PDB_SET);
653 : } else {
654 0 : fullname = smbldap_talloc_single_attribute(
655 : smbldap_get_ldap(ldap_state->smbldap_state),
656 : entry,
657 : get_userattr_key2string(ldap_state->schema_ver,
658 : LDAP_ATTR_CN),
659 : ctx);
660 0 : if (fullname) {
661 0 : pdb_set_fullname(sampass, fullname, PDB_SET);
662 : }
663 : }
664 :
665 0 : dir_drive = smbldap_talloc_single_attribute(
666 : smbldap_get_ldap(ldap_state->smbldap_state),
667 : entry,
668 : get_userattr_key2string(ldap_state->schema_ver,
669 : LDAP_ATTR_HOME_DRIVE),
670 : ctx);
671 0 : if (dir_drive) {
672 0 : pdb_set_dir_drive(sampass, dir_drive, PDB_SET);
673 : } else {
674 0 : pdb_set_dir_drive( sampass, lp_logon_drive(), PDB_DEFAULT );
675 : }
676 :
677 0 : homedir = smbldap_talloc_single_attribute(
678 : smbldap_get_ldap(ldap_state->smbldap_state),
679 : entry,
680 : get_userattr_key2string(ldap_state->schema_ver,
681 : LDAP_ATTR_HOME_PATH),
682 : ctx);
683 0 : if (homedir) {
684 0 : if (expand_explicit) {
685 0 : homedir = talloc_sub_basic(ctx,
686 : username,
687 : domain,
688 : homedir);
689 0 : if (!homedir) {
690 0 : goto fn_exit;
691 : }
692 : }
693 0 : pdb_set_homedir(sampass, homedir, PDB_SET);
694 : } else {
695 0 : pdb_set_homedir(sampass,
696 0 : talloc_sub_basic(ctx, username, domain,
697 : lp_logon_home()),
698 : PDB_DEFAULT);
699 : }
700 :
701 0 : logon_script = smbldap_talloc_single_attribute(
702 : smbldap_get_ldap(ldap_state->smbldap_state),
703 : entry,
704 : get_userattr_key2string(ldap_state->schema_ver,
705 : LDAP_ATTR_LOGON_SCRIPT),
706 : ctx);
707 0 : if (logon_script) {
708 0 : if (expand_explicit) {
709 0 : logon_script = talloc_sub_basic(ctx,
710 : username,
711 : domain,
712 : logon_script);
713 0 : if (!logon_script) {
714 0 : goto fn_exit;
715 : }
716 : }
717 0 : pdb_set_logon_script(sampass, logon_script, PDB_SET);
718 : } else {
719 0 : pdb_set_logon_script(sampass,
720 0 : talloc_sub_basic(ctx, username, domain,
721 : lp_logon_script()),
722 : PDB_DEFAULT );
723 : }
724 :
725 0 : profile_path = smbldap_talloc_single_attribute(
726 : smbldap_get_ldap(ldap_state->smbldap_state),
727 : entry,
728 : get_userattr_key2string(ldap_state->schema_ver,
729 : LDAP_ATTR_PROFILE_PATH),
730 : ctx);
731 0 : if (profile_path) {
732 0 : if (expand_explicit) {
733 0 : profile_path = talloc_sub_basic(ctx,
734 : username,
735 : domain,
736 : profile_path);
737 0 : if (!profile_path) {
738 0 : goto fn_exit;
739 : }
740 : }
741 0 : pdb_set_profile_path(sampass, profile_path, PDB_SET);
742 : } else {
743 0 : pdb_set_profile_path(sampass,
744 0 : talloc_sub_basic(ctx, username, domain,
745 : lp_logon_path()),
746 : PDB_DEFAULT );
747 : }
748 :
749 0 : acct_desc = smbldap_talloc_single_attribute(
750 : smbldap_get_ldap(ldap_state->smbldap_state),
751 : entry,
752 : get_userattr_key2string(ldap_state->schema_ver,
753 : LDAP_ATTR_DESC),
754 : ctx);
755 0 : if (acct_desc) {
756 0 : pdb_set_acct_desc(sampass, acct_desc, PDB_SET);
757 : }
758 :
759 0 : workstations = smbldap_talloc_single_attribute(
760 : smbldap_get_ldap(ldap_state->smbldap_state),
761 : entry,
762 : get_userattr_key2string(ldap_state->schema_ver,
763 : LDAP_ATTR_USER_WKS),
764 : ctx);
765 0 : if (workstations) {
766 0 : pdb_set_workstations(sampass, workstations, PDB_SET);
767 : }
768 :
769 0 : munged_dial = smbldap_talloc_single_attribute(
770 : smbldap_get_ldap(ldap_state->smbldap_state),
771 : entry,
772 : get_userattr_key2string(ldap_state->schema_ver,
773 : LDAP_ATTR_MUNGED_DIAL),
774 : ctx);
775 0 : if (munged_dial) {
776 0 : pdb_set_munged_dial(sampass, munged_dial, PDB_SET);
777 : }
778 :
779 : /* FIXME: hours stuff should be cleaner */
780 :
781 0 : logon_divs = 168;
782 0 : hours_len = 21;
783 0 : memset(hours, 0xff, hours_len);
784 :
785 0 : if (ldap_state->is_nds_ldap) {
786 0 : char *user_dn;
787 0 : size_t pwd_len;
788 0 : char clear_text_pw[512];
789 :
790 : /* Make call to Novell eDirectory ldap extension to get clear text password.
791 : NOTE: This will only work if we have an SSL connection to eDirectory. */
792 0 : user_dn = smbldap_talloc_dn(
793 : ctx, smbldap_get_ldap(ldap_state->smbldap_state),
794 : entry);
795 0 : if (user_dn != NULL) {
796 0 : DEBUG(3, ("init_sam_from_ldap: smbldap_talloc_dn(ctx, %s) returned '%s'\n", username, user_dn));
797 :
798 0 : pwd_len = sizeof(clear_text_pw);
799 0 : if (pdb_nds_get_password(ldap_state->smbldap_state, user_dn, &pwd_len, clear_text_pw) == LDAP_SUCCESS) {
800 0 : nt_lm_owf_gen(clear_text_pw, smbntpwd, smblmpwd);
801 0 : if (!pdb_set_lanman_passwd(sampass, smblmpwd, PDB_SET)) {
802 0 : TALLOC_FREE(user_dn);
803 0 : return False;
804 : }
805 0 : ZERO_STRUCT(smblmpwd);
806 0 : if (!pdb_set_nt_passwd(sampass, smbntpwd, PDB_SET)) {
807 0 : TALLOC_FREE(user_dn);
808 0 : return False;
809 : }
810 0 : ZERO_STRUCT(smbntpwd);
811 0 : use_samba_attrs = False;
812 : }
813 :
814 0 : TALLOC_FREE(user_dn);
815 :
816 : } else {
817 0 : DEBUG(0, ("init_sam_from_ldap: failed to get user_dn for '%s'\n", username));
818 : }
819 : }
820 :
821 0 : if (use_samba_attrs) {
822 0 : temp = smbldap_talloc_single_attribute(
823 : smbldap_get_ldap(ldap_state->smbldap_state),
824 : entry,
825 : get_userattr_key2string(ldap_state->schema_ver,
826 : LDAP_ATTR_LMPW),
827 : ctx);
828 0 : if (temp) {
829 0 : pdb_gethexpwd(temp, smblmpwd);
830 0 : memset((char *)temp, '\0', strlen(temp)+1);
831 0 : if (!pdb_set_lanman_passwd(sampass, smblmpwd, PDB_SET)) {
832 0 : goto fn_exit;
833 : }
834 0 : ZERO_STRUCT(smblmpwd);
835 : }
836 :
837 0 : temp = smbldap_talloc_single_attribute(
838 : smbldap_get_ldap(ldap_state->smbldap_state),
839 : entry,
840 : get_userattr_key2string(ldap_state->schema_ver,
841 : LDAP_ATTR_NTPW),
842 : ctx);
843 0 : if (temp) {
844 0 : pdb_gethexpwd(temp, smbntpwd);
845 0 : memset((char *)temp, '\0', strlen(temp)+1);
846 0 : if (!pdb_set_nt_passwd(sampass, smbntpwd, PDB_SET)) {
847 0 : goto fn_exit;
848 : }
849 0 : ZERO_STRUCT(smbntpwd);
850 : }
851 : }
852 :
853 0 : pwHistLen = 0;
854 :
855 0 : pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY, &pwHistLen);
856 0 : if (pwHistLen > 0){
857 0 : uint8_t *pwhist = NULL;
858 0 : int i;
859 0 : char *history_string = talloc_array(ctx, char,
860 : MAX_PW_HISTORY_LEN*64);
861 :
862 0 : if (!history_string) {
863 0 : goto fn_exit;
864 : }
865 :
866 0 : pwHistLen = MIN(pwHistLen, MAX_PW_HISTORY_LEN);
867 :
868 0 : pwhist = talloc_zero_array(ctx, uint8_t,
869 : pwHistLen * PW_HISTORY_ENTRY_LEN);
870 0 : if (pwhist == NULL) {
871 0 : DEBUG(0, ("init_sam_from_ldap: talloc failed!\n"));
872 0 : goto fn_exit;
873 : }
874 :
875 0 : if (smbldap_get_single_attribute(
876 : smbldap_get_ldap(ldap_state->smbldap_state),
877 : entry,
878 : get_userattr_key2string(ldap_state->schema_ver,
879 : LDAP_ATTR_PWD_HISTORY),
880 : history_string,
881 : MAX_PW_HISTORY_LEN*64)) {
882 0 : bool hex_failed = false;
883 0 : for (i = 0; i < pwHistLen; i++){
884 : /* Get the 16 byte salt. */
885 0 : if (!pdb_gethexpwd(&history_string[i*64],
886 0 : &pwhist[i*PW_HISTORY_ENTRY_LEN])) {
887 0 : hex_failed = true;
888 0 : break;
889 : }
890 : /* Get the 16 byte MD5 hash of salt+passwd. */
891 0 : if (!pdb_gethexpwd(&history_string[(i*64)+32],
892 0 : &pwhist[(i*PW_HISTORY_ENTRY_LEN)+
893 : PW_HISTORY_SALT_LEN])) {
894 0 : hex_failed = True;
895 0 : break;
896 : }
897 : }
898 0 : if (hex_failed) {
899 0 : DEBUG(2,("init_sam_from_ldap: Failed to get password history for user %s\n",
900 : username));
901 0 : memset(pwhist, '\0', pwHistLen * PW_HISTORY_ENTRY_LEN);
902 : }
903 : }
904 0 : if (!pdb_set_pw_history(sampass, pwhist, pwHistLen, PDB_SET)){
905 0 : goto fn_exit;
906 : }
907 : }
908 :
909 0 : temp = smbldap_talloc_single_attribute(
910 : smbldap_get_ldap(ldap_state->smbldap_state),
911 : entry,
912 : get_userattr_key2string(ldap_state->schema_ver,
913 : LDAP_ATTR_ACB_INFO),
914 : ctx);
915 0 : if (temp) {
916 0 : uint32_t acct_ctrl = 0;
917 0 : acct_ctrl = pdb_decode_acct_ctrl(temp);
918 :
919 0 : if (acct_ctrl == 0) {
920 0 : acct_ctrl |= ACB_NORMAL;
921 : }
922 :
923 0 : pdb_set_acct_ctrl(sampass, acct_ctrl, PDB_SET);
924 : }
925 :
926 0 : pdb_set_hours_len(sampass, hours_len, PDB_SET);
927 0 : pdb_set_logon_divs(sampass, logon_divs, PDB_SET);
928 :
929 0 : temp = smbldap_talloc_single_attribute(
930 : smbldap_get_ldap(ldap_state->smbldap_state),
931 : entry,
932 : get_userattr_key2string(ldap_state->schema_ver,
933 : LDAP_ATTR_BAD_PASSWORD_COUNT),
934 : ctx);
935 0 : if (temp) {
936 0 : bad_password_count = (uint32_t) atol(temp);
937 0 : pdb_set_bad_password_count(sampass,
938 : bad_password_count, PDB_SET);
939 : }
940 :
941 0 : temp = smbldap_talloc_single_attribute(
942 : smbldap_get_ldap(ldap_state->smbldap_state),
943 : entry,
944 : get_userattr_key2string(ldap_state->schema_ver,
945 : LDAP_ATTR_BAD_PASSWORD_TIME),
946 : ctx);
947 0 : if (temp) {
948 0 : bad_password_time = (time_t) atol(temp);
949 0 : pdb_set_bad_password_time(sampass, bad_password_time, PDB_SET);
950 : }
951 :
952 :
953 0 : temp = smbldap_talloc_single_attribute(
954 : smbldap_get_ldap(ldap_state->smbldap_state),
955 : entry,
956 : get_userattr_key2string(ldap_state->schema_ver,
957 : LDAP_ATTR_LOGON_COUNT),
958 : ctx);
959 0 : if (temp) {
960 0 : logon_count = (uint32_t) atol(temp);
961 0 : pdb_set_logon_count(sampass, logon_count, PDB_SET);
962 : }
963 :
964 : /* pdb_set_unknown_6(sampass, unknown6, PDB_SET); */
965 :
966 0 : temp = smbldap_talloc_single_attribute(
967 : smbldap_get_ldap(ldap_state->smbldap_state),
968 : entry,
969 : get_userattr_key2string(ldap_state->schema_ver,
970 : LDAP_ATTR_LOGON_HOURS),
971 : ctx);
972 0 : if (temp) {
973 0 : pdb_gethexhours(temp, hours);
974 0 : memset((char *)temp, '\0', strlen(temp) +1);
975 0 : pdb_set_hours(sampass, hours, hours_len, PDB_SET);
976 0 : ZERO_STRUCT(hours);
977 : }
978 :
979 0 : if (lp_parm_bool(-1, "ldapsam", "trusted", False)) {
980 0 : struct passwd unix_pw;
981 0 : bool have_uid = false;
982 0 : bool have_gid = false;
983 0 : struct dom_sid mapped_gsid;
984 0 : const struct dom_sid *primary_gsid;
985 0 : struct unixid id;
986 0 : int error = 0;
987 :
988 0 : ZERO_STRUCT(unix_pw);
989 :
990 0 : unix_pw.pw_name = username;
991 0 : unix_pw.pw_passwd = discard_const_p(char, "x");
992 :
993 0 : temp = smbldap_talloc_single_attribute(
994 : priv2ld(ldap_state),
995 : entry,
996 : "uidNumber",
997 : ctx);
998 0 : if (temp) {
999 : /* We've got a uid, feed the cache */
1000 0 : unix_pw.pw_uid = smb_strtoul(temp,
1001 : NULL,
1002 : 10,
1003 : &error,
1004 : SMB_STR_STANDARD);
1005 0 : if (error != 0) {
1006 0 : DBG_ERR("Failed to convert UID\n");
1007 0 : goto fn_exit;
1008 : }
1009 0 : have_uid = true;
1010 : }
1011 0 : temp = smbldap_talloc_single_attribute(
1012 : priv2ld(ldap_state),
1013 : entry,
1014 : "gidNumber",
1015 : ctx);
1016 0 : if (temp) {
1017 : /* We've got a uid, feed the cache */
1018 0 : unix_pw.pw_gid = smb_strtoul(temp,
1019 : NULL,
1020 : 10,
1021 : &error,
1022 : SMB_STR_STANDARD);
1023 0 : if (error != 0) {
1024 0 : DBG_ERR("Failed to convert GID\n");
1025 0 : goto fn_exit;
1026 : }
1027 0 : have_gid = true;
1028 : }
1029 0 : unix_pw.pw_gecos = smbldap_talloc_single_attribute(
1030 : priv2ld(ldap_state),
1031 : entry,
1032 : "gecos",
1033 : ctx);
1034 0 : if (unix_pw.pw_gecos == NULL) {
1035 0 : unix_pw.pw_gecos = fullname;
1036 : }
1037 0 : unix_pw.pw_dir = smbldap_talloc_single_attribute(
1038 : priv2ld(ldap_state),
1039 : entry,
1040 : "homeDirectory",
1041 : ctx);
1042 0 : if (unix_pw.pw_dir == NULL) {
1043 0 : unix_pw.pw_dir = discard_const_p(char, "");
1044 : }
1045 0 : unix_pw.pw_shell = smbldap_talloc_single_attribute(
1046 : priv2ld(ldap_state),
1047 : entry,
1048 : "loginShell",
1049 : ctx);
1050 0 : if (unix_pw.pw_shell == NULL) {
1051 0 : unix_pw.pw_shell = discard_const_p(char, "");
1052 : }
1053 :
1054 0 : if (have_uid && have_gid) {
1055 0 : sampass->unix_pw = tcopy_passwd(sampass, &unix_pw);
1056 : } else {
1057 0 : sampass->unix_pw = Get_Pwnam_alloc(sampass, unix_pw.pw_name);
1058 : }
1059 :
1060 0 : if (sampass->unix_pw == NULL) {
1061 0 : DEBUG(0,("init_sam_from_ldap: Failed to find Unix account for %s\n",
1062 : pdb_get_username(sampass)));
1063 0 : goto fn_exit;
1064 : }
1065 :
1066 0 : id.id = sampass->unix_pw->pw_uid;
1067 0 : id.type = ID_TYPE_UID;
1068 :
1069 0 : idmap_cache_set_sid2unixid(pdb_get_user_sid(sampass), &id);
1070 :
1071 0 : gid_to_sid(&mapped_gsid, sampass->unix_pw->pw_gid);
1072 0 : primary_gsid = pdb_get_group_sid(sampass);
1073 0 : if (primary_gsid && dom_sid_equal(primary_gsid, &mapped_gsid)) {
1074 0 : id.id = sampass->unix_pw->pw_gid;
1075 0 : id.type = ID_TYPE_GID;
1076 :
1077 0 : idmap_cache_set_sid2unixid(primary_gsid, &id);
1078 : }
1079 : }
1080 :
1081 : /* check the timestamp of the cache vs ldap entry */
1082 0 : if (!(ldap_entry_time = ldapsam_get_entry_timestamp(ldap_state,
1083 : entry))) {
1084 0 : ret = true;
1085 0 : goto fn_exit;
1086 : }
1087 :
1088 : /* see if we have newer updates */
1089 0 : if (!login_cache_read(sampass, &cache_entry)) {
1090 0 : DEBUG (9, ("No cache entry, bad count = %u, bad time = %u\n",
1091 : (unsigned int)pdb_get_bad_password_count(sampass),
1092 : (unsigned int)pdb_get_bad_password_time(sampass)));
1093 0 : ret = true;
1094 0 : goto fn_exit;
1095 : }
1096 :
1097 0 : DEBUG(7, ("ldap time is %u, cache time is %u, bad time = %u\n",
1098 : (unsigned int)ldap_entry_time,
1099 : (unsigned int)cache_entry.entry_timestamp,
1100 : (unsigned int)cache_entry.bad_password_time));
1101 :
1102 0 : if (ldap_entry_time > cache_entry.entry_timestamp) {
1103 : /* cache is older than directory , so
1104 : we need to delete the entry but allow the
1105 : fields to be written out */
1106 0 : login_cache_delentry(sampass);
1107 : } else {
1108 : /* read cache in */
1109 0 : pdb_set_acct_ctrl(sampass,
1110 0 : pdb_get_acct_ctrl(sampass) |
1111 0 : (cache_entry.acct_ctrl & ACB_AUTOLOCK),
1112 : PDB_SET);
1113 0 : pdb_set_bad_password_count(sampass,
1114 0 : cache_entry.bad_password_count,
1115 : PDB_SET);
1116 0 : pdb_set_bad_password_time(sampass,
1117 : cache_entry.bad_password_time,
1118 : PDB_SET);
1119 : }
1120 :
1121 0 : ret = true;
1122 :
1123 0 : fn_exit:
1124 :
1125 0 : TALLOC_FREE(ctx);
1126 0 : return ret;
1127 : }
1128 :
1129 : /**********************************************************************
1130 : Initialize the ldap db from a struct samu. Called on update.
1131 : (Based on init_buffer_from_sam in pdb_tdb.c)
1132 : *********************************************************************/
1133 :
1134 0 : static bool init_ldap_from_sam (struct ldapsam_privates *ldap_state,
1135 : LDAPMessage *existing,
1136 : LDAPMod *** mods, struct samu * sampass,
1137 : bool (*need_update)(const struct samu *,
1138 : enum pdb_elements))
1139 : {
1140 0 : char *temp = NULL;
1141 :
1142 0 : if (mods == NULL || sampass == NULL) {
1143 0 : DEBUG(0, ("init_ldap_from_sam: NULL parameters found!\n"));
1144 0 : return False;
1145 : }
1146 :
1147 0 : *mods = NULL;
1148 :
1149 : /*
1150 : * took out adding "objectclass: sambaAccount"
1151 : * do this on a per-mod basis
1152 : */
1153 0 : if (need_update(sampass, PDB_USERNAME)) {
1154 0 : smbldap_make_mod(smbldap_get_ldap(ldap_state->smbldap_state),
1155 : existing, mods,
1156 : "uid", pdb_get_username(sampass));
1157 0 : if (ldap_state->is_nds_ldap) {
1158 0 : smbldap_make_mod(
1159 : smbldap_get_ldap(ldap_state->smbldap_state),
1160 : existing, mods,
1161 : "cn", pdb_get_username(sampass));
1162 0 : smbldap_make_mod(
1163 : smbldap_get_ldap(ldap_state->smbldap_state),
1164 : existing, mods,
1165 : "sn", pdb_get_username(sampass));
1166 : }
1167 : }
1168 :
1169 0 : DEBUG(2, ("init_ldap_from_sam: Setting entry for user: %s\n", pdb_get_username(sampass)));
1170 :
1171 : /* only update the RID if we actually need to */
1172 0 : if (need_update(sampass, PDB_USERSID)) {
1173 0 : struct dom_sid_buf sid_str;
1174 0 : const struct dom_sid *user_sid = pdb_get_user_sid(sampass);
1175 :
1176 0 : switch ( ldap_state->schema_ver ) {
1177 0 : case SCHEMAVER_SAMBASAMACCOUNT:
1178 0 : smbldap_make_mod(
1179 : smbldap_get_ldap(
1180 : ldap_state->smbldap_state),
1181 : existing, mods,
1182 : get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_USER_SID),
1183 0 : dom_sid_str_buf(user_sid, &sid_str));
1184 0 : break;
1185 :
1186 0 : default:
1187 0 : DEBUG(0,("init_ldap_from_sam: unknown schema version specified\n"));
1188 0 : break;
1189 : }
1190 : }
1191 :
1192 : /* we don't need to store the primary group RID - so leaving it
1193 : 'free' to hang off the unix primary group makes life easier */
1194 :
1195 0 : if (need_update(sampass, PDB_GROUPSID)) {
1196 0 : struct dom_sid_buf sid_str;
1197 0 : const struct dom_sid *group_sid = pdb_get_group_sid(sampass);
1198 :
1199 0 : switch ( ldap_state->schema_ver ) {
1200 0 : case SCHEMAVER_SAMBASAMACCOUNT:
1201 0 : smbldap_make_mod(
1202 : smbldap_get_ldap(
1203 : ldap_state->smbldap_state),
1204 : existing, mods,
1205 : get_userattr_key2string(ldap_state->schema_ver,
1206 : LDAP_ATTR_PRIMARY_GROUP_SID),
1207 0 : dom_sid_str_buf(group_sid, &sid_str));
1208 0 : break;
1209 :
1210 0 : default:
1211 0 : DEBUG(0,("init_ldap_from_sam: unknown schema version specified\n"));
1212 0 : break;
1213 : }
1214 :
1215 : }
1216 :
1217 : /* displayName, cn, and gecos should all be the same
1218 : * most easily accomplished by giving them the same OID
1219 : * gecos isn't set here b/c it should be handled by the
1220 : * add-user script
1221 : * We change displayName only and fall back to cn if
1222 : * it does not exist.
1223 : */
1224 :
1225 0 : if (need_update(sampass, PDB_FULLNAME))
1226 0 : smbldap_make_mod(smbldap_get_ldap(ldap_state->smbldap_state),
1227 : existing, mods,
1228 : get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_DISPLAY_NAME),
1229 : pdb_get_fullname(sampass));
1230 :
1231 0 : if (need_update(sampass, PDB_ACCTDESC))
1232 0 : smbldap_make_mod(smbldap_get_ldap(ldap_state->smbldap_state),
1233 : existing, mods,
1234 : get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_DESC),
1235 : pdb_get_acct_desc(sampass));
1236 :
1237 0 : if (need_update(sampass, PDB_WORKSTATIONS))
1238 0 : smbldap_make_mod(smbldap_get_ldap(ldap_state->smbldap_state),
1239 : existing, mods,
1240 : get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_USER_WKS),
1241 : pdb_get_workstations(sampass));
1242 :
1243 0 : if (need_update(sampass, PDB_MUNGEDDIAL))
1244 0 : smbldap_make_mod(smbldap_get_ldap(ldap_state->smbldap_state),
1245 : existing, mods,
1246 : get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_MUNGED_DIAL),
1247 : pdb_get_munged_dial(sampass));
1248 :
1249 0 : if (need_update(sampass, PDB_SMBHOME))
1250 0 : smbldap_make_mod(smbldap_get_ldap(ldap_state->smbldap_state),
1251 : existing, mods,
1252 : get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_HOME_PATH),
1253 : pdb_get_homedir(sampass));
1254 :
1255 0 : if (need_update(sampass, PDB_DRIVE))
1256 0 : smbldap_make_mod(smbldap_get_ldap(ldap_state->smbldap_state),
1257 : existing, mods,
1258 : get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_HOME_DRIVE),
1259 : pdb_get_dir_drive(sampass));
1260 :
1261 0 : if (need_update(sampass, PDB_LOGONSCRIPT))
1262 0 : smbldap_make_mod(smbldap_get_ldap(ldap_state->smbldap_state),
1263 : existing, mods,
1264 : get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_LOGON_SCRIPT),
1265 : pdb_get_logon_script(sampass));
1266 :
1267 0 : if (need_update(sampass, PDB_PROFILE))
1268 0 : smbldap_make_mod(smbldap_get_ldap(ldap_state->smbldap_state),
1269 : existing, mods,
1270 : get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_PROFILE_PATH),
1271 : pdb_get_profile_path(sampass));
1272 :
1273 0 : if (asprintf(&temp, "%li", (long int)pdb_get_logon_time(sampass)) < 0) {
1274 0 : return false;
1275 : }
1276 0 : if (need_update(sampass, PDB_LOGONTIME))
1277 0 : smbldap_make_mod(smbldap_get_ldap(ldap_state->smbldap_state),
1278 : existing, mods,
1279 : get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_LOGON_TIME), temp);
1280 0 : SAFE_FREE(temp);
1281 :
1282 0 : if (asprintf(&temp, "%li", (long int)pdb_get_logoff_time(sampass)) < 0) {
1283 0 : return false;
1284 : }
1285 0 : if (need_update(sampass, PDB_LOGOFFTIME))
1286 0 : smbldap_make_mod(smbldap_get_ldap(ldap_state->smbldap_state),
1287 : existing, mods,
1288 : get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_LOGOFF_TIME), temp);
1289 0 : SAFE_FREE(temp);
1290 :
1291 0 : if (asprintf(&temp, "%li", (long int)pdb_get_kickoff_time(sampass)) < 0) {
1292 0 : return false;
1293 : }
1294 0 : if (need_update(sampass, PDB_KICKOFFTIME))
1295 0 : smbldap_make_mod(smbldap_get_ldap(ldap_state->smbldap_state),
1296 : existing, mods,
1297 : get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_KICKOFF_TIME), temp);
1298 0 : SAFE_FREE(temp);
1299 :
1300 0 : if (asprintf(&temp, "%li", (long int)pdb_get_pass_can_change_time_noncalc(sampass)) < 0) {
1301 0 : return false;
1302 : }
1303 0 : if (need_update(sampass, PDB_CANCHANGETIME))
1304 0 : smbldap_make_mod(smbldap_get_ldap(ldap_state->smbldap_state),
1305 : existing, mods,
1306 : get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_PWD_CAN_CHANGE), temp);
1307 0 : SAFE_FREE(temp);
1308 :
1309 0 : if ((pdb_get_acct_ctrl(sampass)&(ACB_WSTRUST|ACB_SVRTRUST|ACB_DOMTRUST))
1310 0 : || (lp_ldap_passwd_sync()!=LDAP_PASSWD_SYNC_ONLY)) {
1311 :
1312 0 : if (need_update(sampass, PDB_LMPASSWD)) {
1313 0 : const uchar *lm_pw = pdb_get_lanman_passwd(sampass);
1314 0 : if (lm_pw) {
1315 0 : char pwstr[34];
1316 0 : pdb_sethexpwd(pwstr, lm_pw,
1317 : pdb_get_acct_ctrl(sampass));
1318 0 : smbldap_make_mod(
1319 : smbldap_get_ldap(
1320 : ldap_state->smbldap_state),
1321 : existing, mods,
1322 : get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_LMPW),
1323 : pwstr);
1324 : } else {
1325 0 : smbldap_make_mod(
1326 : smbldap_get_ldap(
1327 : ldap_state->smbldap_state),
1328 : existing, mods,
1329 : get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_LMPW),
1330 : NULL);
1331 : }
1332 : }
1333 0 : if (need_update(sampass, PDB_NTPASSWD)) {
1334 0 : const uchar *nt_pw = pdb_get_nt_passwd(sampass);
1335 0 : if (nt_pw) {
1336 0 : char pwstr[34];
1337 0 : pdb_sethexpwd(pwstr, nt_pw,
1338 : pdb_get_acct_ctrl(sampass));
1339 0 : smbldap_make_mod(
1340 : smbldap_get_ldap(
1341 : ldap_state->smbldap_state),
1342 : existing, mods,
1343 : get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_NTPW),
1344 : pwstr);
1345 : } else {
1346 0 : smbldap_make_mod(
1347 : smbldap_get_ldap(
1348 : ldap_state->smbldap_state),
1349 : existing, mods,
1350 : get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_NTPW),
1351 : NULL);
1352 : }
1353 : }
1354 :
1355 0 : if (need_update(sampass, PDB_PWHISTORY)) {
1356 0 : char *pwstr = NULL;
1357 0 : uint32_t pwHistLen = 0;
1358 0 : pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY, &pwHistLen);
1359 :
1360 0 : pwstr = SMB_MALLOC_ARRAY(char, 1024);
1361 0 : if (!pwstr) {
1362 0 : return false;
1363 : }
1364 0 : if (pwHistLen == 0) {
1365 : /* Remove any password history from the LDAP store. */
1366 0 : memset(pwstr, '0', 64); /* NOTE !!!! '0' *NOT '\0' */
1367 0 : pwstr[64] = '\0';
1368 : } else {
1369 0 : int i;
1370 0 : uint32_t currHistLen = 0;
1371 0 : const uint8_t *pwhist = pdb_get_pw_history(sampass, &currHistLen);
1372 0 : if (pwhist != NULL) {
1373 : /* We can only store (1024-1/64 password history entries. */
1374 0 : pwHistLen = MIN(pwHistLen, ((1024-1)/64));
1375 0 : for (i=0; i< pwHistLen && i < currHistLen; i++) {
1376 : /* Store the salt. */
1377 0 : pdb_sethexpwd(&pwstr[i*64], &pwhist[i*PW_HISTORY_ENTRY_LEN], 0);
1378 : /* Followed by the md5 hash of salt + md4 hash */
1379 0 : pdb_sethexpwd(&pwstr[(i*64)+32],
1380 0 : &pwhist[(i*PW_HISTORY_ENTRY_LEN)+PW_HISTORY_SALT_LEN], 0);
1381 0 : DEBUG(100, ("pwstr=%s\n", pwstr));
1382 : }
1383 : }
1384 : }
1385 0 : smbldap_make_mod(
1386 : smbldap_get_ldap(ldap_state->smbldap_state),
1387 : existing, mods,
1388 : get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_PWD_HISTORY),
1389 : pwstr);
1390 0 : SAFE_FREE(pwstr);
1391 : }
1392 :
1393 0 : if (need_update(sampass, PDB_PASSLASTSET)) {
1394 0 : if (asprintf(&temp, "%li",
1395 0 : (long int)pdb_get_pass_last_set_time(sampass)) < 0) {
1396 0 : return false;
1397 : }
1398 0 : smbldap_make_mod(
1399 : smbldap_get_ldap(ldap_state->smbldap_state),
1400 : existing, mods,
1401 : get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_PWD_LAST_SET),
1402 : temp);
1403 0 : SAFE_FREE(temp);
1404 : }
1405 : }
1406 :
1407 0 : if (need_update(sampass, PDB_HOURS)) {
1408 0 : const uint8_t *hours = pdb_get_hours(sampass);
1409 0 : if (hours) {
1410 0 : char hourstr[44];
1411 0 : pdb_sethexhours(hourstr, hours);
1412 0 : smbldap_make_mod(
1413 : smbldap_get_ldap(ldap_state->smbldap_state),
1414 : existing,
1415 : mods,
1416 : get_userattr_key2string(ldap_state->schema_ver,
1417 : LDAP_ATTR_LOGON_HOURS),
1418 : hourstr);
1419 : }
1420 : }
1421 :
1422 0 : if (need_update(sampass, PDB_ACCTCTRL))
1423 0 : smbldap_make_mod(
1424 : smbldap_get_ldap(ldap_state->smbldap_state),
1425 : existing, mods,
1426 : get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_ACB_INFO),
1427 0 : pdb_encode_acct_ctrl (pdb_get_acct_ctrl(sampass), NEW_PW_FORMAT_SPACE_PADDED_LEN));
1428 :
1429 : /* password lockout cache:
1430 : - If we are now autolocking or clearing, we write to ldap
1431 : - If we are clearing, we delete the cache entry
1432 : - If the count is > 0, we update the cache
1433 :
1434 : This even means when autolocking, we cache, just in case the
1435 : update doesn't work, and we have to cache the autolock flag */
1436 :
1437 0 : if (need_update(sampass, PDB_BAD_PASSWORD_COUNT)) /* &&
1438 : need_update(sampass, PDB_BAD_PASSWORD_TIME)) */ {
1439 0 : uint16_t badcount = pdb_get_bad_password_count(sampass);
1440 0 : time_t badtime = pdb_get_bad_password_time(sampass);
1441 0 : uint32_t pol;
1442 0 : pdb_get_account_policy(PDB_POLICY_BAD_ATTEMPT_LOCKOUT, &pol);
1443 :
1444 0 : DEBUG(3, ("updating bad password fields, policy=%u, count=%u, time=%u\n",
1445 : (unsigned int)pol, (unsigned int)badcount, (unsigned int)badtime));
1446 :
1447 0 : if ((badcount >= pol) || (badcount == 0)) {
1448 0 : DEBUG(7, ("making mods to update ldap, count=%u, time=%u\n",
1449 : (unsigned int)badcount, (unsigned int)badtime));
1450 0 : if (asprintf(&temp, "%li", (long)badcount) < 0) {
1451 0 : return false;
1452 : }
1453 0 : smbldap_make_mod(
1454 : smbldap_get_ldap(ldap_state->smbldap_state),
1455 : existing, mods,
1456 : get_userattr_key2string(
1457 : ldap_state->schema_ver,
1458 : LDAP_ATTR_BAD_PASSWORD_COUNT),
1459 : temp);
1460 0 : SAFE_FREE(temp);
1461 :
1462 0 : if (asprintf(&temp, "%li", (long int)badtime) < 0) {
1463 0 : return false;
1464 : }
1465 0 : smbldap_make_mod(
1466 : smbldap_get_ldap(ldap_state->smbldap_state),
1467 : existing, mods,
1468 : get_userattr_key2string(
1469 : ldap_state->schema_ver,
1470 : LDAP_ATTR_BAD_PASSWORD_TIME),
1471 : temp);
1472 0 : SAFE_FREE(temp);
1473 : }
1474 0 : if (badcount == 0) {
1475 0 : DEBUG(7, ("bad password count is reset, deleting login cache entry for %s\n", pdb_get_nt_username(sampass)));
1476 0 : login_cache_delentry(sampass);
1477 : } else {
1478 0 : struct login_cache cache_entry;
1479 :
1480 0 : cache_entry.entry_timestamp = time(NULL);
1481 0 : cache_entry.acct_ctrl = pdb_get_acct_ctrl(sampass);
1482 0 : cache_entry.bad_password_count = badcount;
1483 0 : cache_entry.bad_password_time = badtime;
1484 :
1485 0 : DEBUG(7, ("Updating bad password count and time in login cache\n"));
1486 0 : login_cache_write(sampass, &cache_entry);
1487 : }
1488 : }
1489 :
1490 0 : return True;
1491 : }
1492 :
1493 : /**********************************************************************
1494 : End enumeration of the LDAP password list.
1495 : *********************************************************************/
1496 :
1497 0 : static void ldapsam_endsampwent(struct pdb_methods *my_methods)
1498 : {
1499 0 : struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
1500 0 : if (ldap_state->result) {
1501 0 : ldap_msgfree(ldap_state->result);
1502 0 : ldap_state->result = NULL;
1503 : }
1504 0 : }
1505 :
1506 0 : static void append_attr(TALLOC_CTX *mem_ctx, const char ***attr_list,
1507 : const char *new_attr)
1508 : {
1509 0 : int i;
1510 :
1511 0 : if (new_attr == NULL) {
1512 0 : return;
1513 : }
1514 :
1515 0 : for (i=0; (*attr_list)[i] != NULL; i++) {
1516 0 : ;
1517 : }
1518 :
1519 0 : (*attr_list) = talloc_realloc(mem_ctx, (*attr_list),
1520 : const char *, i+2);
1521 0 : SMB_ASSERT((*attr_list) != NULL);
1522 0 : (*attr_list)[i] = talloc_strdup((*attr_list), new_attr);
1523 0 : (*attr_list)[i+1] = NULL;
1524 : }
1525 :
1526 0 : static void ldapsam_add_unix_attributes(TALLOC_CTX *mem_ctx,
1527 : const char ***attr_list)
1528 : {
1529 0 : append_attr(mem_ctx, attr_list, "uidNumber");
1530 0 : append_attr(mem_ctx, attr_list, "gidNumber");
1531 0 : append_attr(mem_ctx, attr_list, "homeDirectory");
1532 0 : append_attr(mem_ctx, attr_list, "loginShell");
1533 0 : append_attr(mem_ctx, attr_list, "gecos");
1534 0 : }
1535 :
1536 : /**********************************************************************
1537 : Get struct samu entry from LDAP by username.
1538 : *********************************************************************/
1539 :
1540 0 : static NTSTATUS ldapsam_getsampwnam(struct pdb_methods *my_methods, struct samu *user, const char *sname)
1541 : {
1542 0 : NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
1543 0 : struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
1544 0 : LDAPMessage *result = NULL;
1545 0 : LDAPMessage *entry = NULL;
1546 0 : int count;
1547 0 : const char ** attr_list;
1548 0 : int rc;
1549 :
1550 0 : attr_list = get_userattr_list( user, ldap_state->schema_ver );
1551 0 : append_attr(user, &attr_list,
1552 : get_userattr_key2string(ldap_state->schema_ver,
1553 : LDAP_ATTR_MOD_TIMESTAMP));
1554 0 : ldapsam_add_unix_attributes(user, &attr_list);
1555 0 : rc = ldapsam_search_suffix_by_name(ldap_state, sname, &result,
1556 : attr_list);
1557 0 : TALLOC_FREE( attr_list );
1558 :
1559 0 : if ( rc != LDAP_SUCCESS )
1560 0 : return NT_STATUS_NO_SUCH_USER;
1561 :
1562 0 : count = ldap_count_entries(smbldap_get_ldap(ldap_state->smbldap_state),
1563 : result);
1564 :
1565 0 : if (count < 1) {
1566 0 : DEBUG(4, ("ldapsam_getsampwnam: Unable to locate user [%s] count=%d\n", sname, count));
1567 0 : ldap_msgfree(result);
1568 0 : return NT_STATUS_NO_SUCH_USER;
1569 0 : } else if (count > 1) {
1570 0 : DEBUG(1, ("ldapsam_getsampwnam: Duplicate entries for this user [%s] Failing. count=%d\n", sname, count));
1571 0 : ldap_msgfree(result);
1572 0 : return NT_STATUS_NO_SUCH_USER;
1573 : }
1574 :
1575 0 : entry = ldap_first_entry(smbldap_get_ldap(ldap_state->smbldap_state),
1576 : result);
1577 0 : if (entry) {
1578 0 : if (!init_sam_from_ldap(ldap_state, user, entry)) {
1579 0 : DEBUG(1,("ldapsam_getsampwnam: init_sam_from_ldap failed for user '%s'!\n", sname));
1580 0 : ldap_msgfree(result);
1581 0 : return NT_STATUS_NO_SUCH_USER;
1582 : }
1583 0 : pdb_set_backend_private_data(user, result, NULL,
1584 : my_methods, PDB_CHANGED);
1585 0 : smbldap_talloc_autofree_ldapmsg(user, result);
1586 0 : ret = NT_STATUS_OK;
1587 : } else {
1588 0 : ldap_msgfree(result);
1589 : }
1590 0 : return ret;
1591 : }
1592 :
1593 0 : static int ldapsam_get_ldap_user_by_sid(struct ldapsam_privates *ldap_state,
1594 : const struct dom_sid *sid, LDAPMessage **result)
1595 : {
1596 0 : int rc = -1;
1597 0 : const char ** attr_list;
1598 :
1599 0 : switch ( ldap_state->schema_ver ) {
1600 0 : case SCHEMAVER_SAMBASAMACCOUNT: {
1601 0 : TALLOC_CTX *tmp_ctx = talloc_new(NULL);
1602 0 : if (tmp_ctx == NULL) {
1603 0 : return LDAP_NO_MEMORY;
1604 : }
1605 :
1606 0 : attr_list = get_userattr_list(tmp_ctx,
1607 : ldap_state->schema_ver);
1608 0 : append_attr(tmp_ctx, &attr_list,
1609 : get_userattr_key2string(
1610 : ldap_state->schema_ver,
1611 : LDAP_ATTR_MOD_TIMESTAMP));
1612 0 : ldapsam_add_unix_attributes(tmp_ctx, &attr_list);
1613 0 : rc = ldapsam_search_suffix_by_sid(ldap_state, sid,
1614 : result, attr_list);
1615 0 : TALLOC_FREE(tmp_ctx);
1616 :
1617 0 : if ( rc != LDAP_SUCCESS )
1618 0 : return rc;
1619 0 : break;
1620 : }
1621 :
1622 0 : default:
1623 0 : DEBUG(0,("Invalid schema version specified\n"));
1624 0 : break;
1625 : }
1626 0 : return rc;
1627 : }
1628 :
1629 : /**********************************************************************
1630 : Get struct samu entry from LDAP by SID.
1631 : *********************************************************************/
1632 :
1633 0 : static NTSTATUS ldapsam_getsampwsid(struct pdb_methods *my_methods, struct samu * user, const struct dom_sid *sid)
1634 : {
1635 0 : struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
1636 0 : LDAPMessage *result = NULL;
1637 0 : LDAPMessage *entry = NULL;
1638 0 : int count;
1639 0 : int rc;
1640 :
1641 0 : rc = ldapsam_get_ldap_user_by_sid(ldap_state,
1642 : sid, &result);
1643 0 : if (rc != LDAP_SUCCESS)
1644 0 : return NT_STATUS_NO_SUCH_USER;
1645 :
1646 0 : count = ldap_count_entries(smbldap_get_ldap(ldap_state->smbldap_state),
1647 : result);
1648 :
1649 0 : if (count < 1) {
1650 0 : struct dom_sid_buf buf;
1651 0 : DEBUG(4, ("ldapsam_getsampwsid: Unable to locate SID [%s] "
1652 : "count=%d\n",
1653 : dom_sid_str_buf(sid, &buf),
1654 : count));
1655 0 : ldap_msgfree(result);
1656 0 : return NT_STATUS_NO_SUCH_USER;
1657 0 : } else if (count > 1) {
1658 0 : struct dom_sid_buf buf;
1659 0 : DEBUG(1, ("ldapsam_getsampwsid: More than one user with SID "
1660 : "[%s]. Failing. count=%d\n",
1661 : dom_sid_str_buf(sid, &buf),
1662 : count));
1663 0 : ldap_msgfree(result);
1664 0 : return NT_STATUS_NO_SUCH_USER;
1665 : }
1666 :
1667 0 : entry = ldap_first_entry(smbldap_get_ldap(ldap_state->smbldap_state),
1668 : result);
1669 0 : if (!entry) {
1670 0 : ldap_msgfree(result);
1671 0 : return NT_STATUS_NO_SUCH_USER;
1672 : }
1673 :
1674 0 : if (!init_sam_from_ldap(ldap_state, user, entry)) {
1675 0 : DEBUG(1,("ldapsam_getsampwsid: init_sam_from_ldap failed!\n"));
1676 0 : ldap_msgfree(result);
1677 0 : return NT_STATUS_NO_SUCH_USER;
1678 : }
1679 :
1680 0 : pdb_set_backend_private_data(user, result, NULL,
1681 : my_methods, PDB_CHANGED);
1682 0 : smbldap_talloc_autofree_ldapmsg(user, result);
1683 0 : return NT_STATUS_OK;
1684 : }
1685 :
1686 : /********************************************************************
1687 : Do the actual modification - also change a plaintext password if
1688 : it it set.
1689 : **********************************************************************/
1690 :
1691 0 : static NTSTATUS ldapsam_modify_entry(struct pdb_methods *my_methods,
1692 : struct samu *newpwd, char *dn,
1693 : LDAPMod **mods, int ldap_op,
1694 : bool (*need_update)(const struct samu *, enum pdb_elements))
1695 : {
1696 0 : struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
1697 0 : int rc;
1698 :
1699 0 : if (!newpwd || !dn) {
1700 0 : return NT_STATUS_INVALID_PARAMETER;
1701 : }
1702 :
1703 0 : if (!(pdb_get_acct_ctrl(newpwd)&(ACB_WSTRUST|ACB_SVRTRUST|ACB_DOMTRUST)) &&
1704 0 : (lp_ldap_passwd_sync() != LDAP_PASSWD_SYNC_OFF) &&
1705 0 : need_update(newpwd, PDB_PLAINTEXT_PW) &&
1706 0 : (pdb_get_plaintext_passwd(newpwd)!=NULL)) {
1707 0 : BerElement *ber;
1708 0 : struct berval *bv;
1709 0 : char *retoid = NULL;
1710 0 : struct berval *retdata = NULL;
1711 0 : char *utf8_password;
1712 0 : char *utf8_dn;
1713 0 : size_t converted_size;
1714 0 : int ret;
1715 :
1716 0 : if (!ldap_state->is_nds_ldap) {
1717 :
1718 0 : if (!smbldap_has_extension(
1719 : smbldap_get_ldap(
1720 : ldap_state->smbldap_state),
1721 : LDAP_EXOP_MODIFY_PASSWD)) {
1722 0 : DEBUG(2, ("ldap password change requested, but LDAP "
1723 : "server does not support it -- ignoring\n"));
1724 0 : return NT_STATUS_OK;
1725 : }
1726 : }
1727 :
1728 0 : if (!push_utf8_talloc(talloc_tos(), &utf8_password,
1729 : pdb_get_plaintext_passwd(newpwd),
1730 : &converted_size))
1731 : {
1732 0 : return NT_STATUS_NO_MEMORY;
1733 : }
1734 :
1735 0 : if (!push_utf8_talloc(talloc_tos(), &utf8_dn, dn, &converted_size)) {
1736 0 : TALLOC_FREE(utf8_password);
1737 0 : return NT_STATUS_NO_MEMORY;
1738 : }
1739 :
1740 0 : if ((ber = ber_alloc_t(LBER_USE_DER))==NULL) {
1741 0 : DEBUG(0,("ber_alloc_t returns NULL\n"));
1742 0 : TALLOC_FREE(utf8_password);
1743 0 : TALLOC_FREE(utf8_dn);
1744 0 : return NT_STATUS_UNSUCCESSFUL;
1745 : }
1746 :
1747 0 : if ((ber_printf (ber, "{") < 0) ||
1748 0 : (ber_printf (ber, "ts", LDAP_TAG_EXOP_MODIFY_PASSWD_ID,
1749 : utf8_dn) < 0)) {
1750 0 : DEBUG(0,("ldapsam_modify_entry: ber_printf returns a "
1751 : "value <0\n"));
1752 0 : ber_free(ber,1);
1753 0 : TALLOC_FREE(utf8_dn);
1754 0 : TALLOC_FREE(utf8_password);
1755 0 : return NT_STATUS_UNSUCCESSFUL;
1756 : }
1757 :
1758 0 : if ((utf8_password != NULL) && (*utf8_password != '\0')) {
1759 0 : ret = ber_printf(ber, "ts}",
1760 : LDAP_TAG_EXOP_MODIFY_PASSWD_NEW,
1761 : utf8_password);
1762 : } else {
1763 0 : ret = ber_printf(ber, "}");
1764 : }
1765 :
1766 0 : if (ret < 0) {
1767 0 : DEBUG(0,("ldapsam_modify_entry: ber_printf returns a "
1768 : "value <0\n"));
1769 0 : ber_free(ber,1);
1770 0 : TALLOC_FREE(utf8_dn);
1771 0 : TALLOC_FREE(utf8_password);
1772 0 : return NT_STATUS_UNSUCCESSFUL;
1773 : }
1774 :
1775 0 : if ((rc = ber_flatten (ber, &bv))<0) {
1776 0 : DEBUG(0,("ldapsam_modify_entry: ber_flatten returns a value <0\n"));
1777 0 : ber_free(ber,1);
1778 0 : TALLOC_FREE(utf8_dn);
1779 0 : TALLOC_FREE(utf8_password);
1780 0 : return NT_STATUS_UNSUCCESSFUL;
1781 : }
1782 :
1783 0 : TALLOC_FREE(utf8_dn);
1784 0 : TALLOC_FREE(utf8_password);
1785 0 : ber_free(ber, 1);
1786 :
1787 0 : if (!ldap_state->is_nds_ldap) {
1788 0 : rc = smbldap_extended_operation(ldap_state->smbldap_state,
1789 : LDAP_EXOP_MODIFY_PASSWD,
1790 : bv, NULL, NULL, &retoid,
1791 : &retdata);
1792 : } else {
1793 0 : rc = pdb_nds_set_password(ldap_state->smbldap_state, dn,
1794 : pdb_get_plaintext_passwd(newpwd));
1795 : }
1796 0 : if (rc != LDAP_SUCCESS) {
1797 0 : char *ld_error = NULL;
1798 :
1799 0 : if (rc == LDAP_OBJECT_CLASS_VIOLATION) {
1800 0 : DEBUG(3, ("Could not set userPassword "
1801 : "attribute due to an objectClass "
1802 : "violation -- ignoring\n"));
1803 0 : ber_bvfree(bv);
1804 0 : return NT_STATUS_OK;
1805 : }
1806 :
1807 0 : ldap_get_option(
1808 : smbldap_get_ldap(ldap_state->smbldap_state),
1809 : LDAP_OPT_ERROR_STRING,
1810 : &ld_error);
1811 0 : DEBUG(0,("ldapsam_modify_entry: LDAP Password could not be changed for user %s: %s\n\t%s\n",
1812 : pdb_get_username(newpwd), ldap_err2string(rc), ld_error?ld_error:"unknown"));
1813 0 : SAFE_FREE(ld_error);
1814 0 : ber_bvfree(bv);
1815 : #if defined(LDAP_CONSTRAINT_VIOLATION)
1816 0 : if (rc == LDAP_CONSTRAINT_VIOLATION)
1817 0 : return NT_STATUS_PASSWORD_RESTRICTION;
1818 : #endif
1819 0 : return NT_STATUS_UNSUCCESSFUL;
1820 : } else {
1821 0 : DEBUG(3,("ldapsam_modify_entry: LDAP Password changed for user %s\n",pdb_get_username(newpwd)));
1822 : #ifdef DEBUG_PASSWORD
1823 0 : DEBUG(100,("ldapsam_modify_entry: LDAP Password changed to %s\n",pdb_get_plaintext_passwd(newpwd)));
1824 : #endif
1825 0 : if (retdata)
1826 0 : ber_bvfree(retdata);
1827 0 : if (retoid)
1828 0 : ldap_memfree(retoid);
1829 : }
1830 0 : ber_bvfree(bv);
1831 : }
1832 :
1833 0 : if (!mods) {
1834 0 : DEBUG(5,("ldapsam_modify_entry: mods is empty: nothing to modify\n"));
1835 : /* may be password change below however */
1836 : } else {
1837 0 : switch(ldap_op) {
1838 0 : case LDAP_MOD_ADD:
1839 0 : if (ldap_state->is_nds_ldap) {
1840 0 : smbldap_set_mod(&mods, LDAP_MOD_ADD,
1841 : "objectclass",
1842 : "inetOrgPerson");
1843 : } else {
1844 0 : smbldap_set_mod(&mods, LDAP_MOD_ADD,
1845 : "objectclass",
1846 : LDAP_OBJ_ACCOUNT);
1847 : }
1848 0 : rc = smbldap_add(ldap_state->smbldap_state,
1849 : dn, mods);
1850 0 : break;
1851 0 : case LDAP_MOD_REPLACE:
1852 0 : rc = smbldap_modify(ldap_state->smbldap_state,
1853 : dn ,mods);
1854 0 : break;
1855 0 : default:
1856 0 : DEBUG(0,("ldapsam_modify_entry: Wrong LDAP operation type: %d!\n",
1857 : ldap_op));
1858 0 : return NT_STATUS_INVALID_PARAMETER;
1859 : }
1860 :
1861 0 : if (rc!=LDAP_SUCCESS) {
1862 0 : return NT_STATUS_UNSUCCESSFUL;
1863 : }
1864 : }
1865 :
1866 0 : return NT_STATUS_OK;
1867 : }
1868 :
1869 : /**********************************************************************
1870 : Delete entry from LDAP for username.
1871 : *********************************************************************/
1872 :
1873 0 : static NTSTATUS ldapsam_delete_sam_account(struct pdb_methods *my_methods,
1874 : struct samu * sam_acct)
1875 : {
1876 0 : struct ldapsam_privates *priv =
1877 : (struct ldapsam_privates *)my_methods->private_data;
1878 0 : const char *sname;
1879 0 : int rc;
1880 0 : LDAPMessage *msg, *entry;
1881 0 : NTSTATUS result = NT_STATUS_NO_MEMORY;
1882 0 : const char **attr_list;
1883 0 : TALLOC_CTX *mem_ctx;
1884 :
1885 0 : if (!sam_acct) {
1886 0 : DEBUG(0, ("ldapsam_delete_sam_account: sam_acct was NULL!\n"));
1887 0 : return NT_STATUS_INVALID_PARAMETER;
1888 : }
1889 :
1890 0 : sname = pdb_get_username(sam_acct);
1891 :
1892 0 : DEBUG(3, ("ldapsam_delete_sam_account: Deleting user %s from "
1893 : "LDAP.\n", sname));
1894 :
1895 0 : mem_ctx = talloc_new(NULL);
1896 0 : if (mem_ctx == NULL) {
1897 0 : DEBUG(0, ("talloc_new failed\n"));
1898 0 : goto done;
1899 : }
1900 :
1901 0 : attr_list = get_userattr_delete_list(mem_ctx, priv->schema_ver );
1902 0 : if (attr_list == NULL) {
1903 0 : goto done;
1904 : }
1905 :
1906 0 : rc = ldapsam_search_suffix_by_name(priv, sname, &msg, attr_list);
1907 :
1908 0 : if ((rc != LDAP_SUCCESS) ||
1909 0 : (ldap_count_entries(priv2ld(priv), msg) != 1) ||
1910 0 : ((entry = ldap_first_entry(priv2ld(priv), msg)) == NULL)) {
1911 0 : DEBUG(5, ("Could not find user %s\n", sname));
1912 0 : result = NT_STATUS_NO_SUCH_USER;
1913 0 : goto done;
1914 : }
1915 :
1916 0 : rc = ldapsam_delete_entry(
1917 : priv, mem_ctx, entry,
1918 0 : priv->schema_ver == SCHEMAVER_SAMBASAMACCOUNT ?
1919 : LDAP_OBJ_SAMBASAMACCOUNT : 0,
1920 : attr_list);
1921 :
1922 0 : result = (rc == LDAP_SUCCESS) ?
1923 0 : NT_STATUS_OK : NT_STATUS_ACCESS_DENIED;
1924 :
1925 0 : done:
1926 0 : TALLOC_FREE(mem_ctx);
1927 0 : return result;
1928 : }
1929 :
1930 : /**********************************************************************
1931 : Update struct samu.
1932 : *********************************************************************/
1933 :
1934 0 : static NTSTATUS ldapsam_update_sam_account(struct pdb_methods *my_methods, struct samu * newpwd)
1935 : {
1936 0 : NTSTATUS ret;
1937 0 : struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
1938 0 : int rc = 0;
1939 0 : char *dn;
1940 0 : LDAPMessage *result = NULL;
1941 0 : LDAPMessage *entry = NULL;
1942 0 : LDAPMod **mods = NULL;
1943 0 : const char **attr_list;
1944 :
1945 0 : result = (LDAPMessage *)pdb_get_backend_private_data(newpwd, my_methods);
1946 0 : if (!result) {
1947 0 : attr_list = get_userattr_list(NULL, ldap_state->schema_ver);
1948 0 : if (pdb_get_username(newpwd) == NULL) {
1949 0 : return NT_STATUS_INVALID_PARAMETER;
1950 : }
1951 0 : rc = ldapsam_search_suffix_by_name(ldap_state, pdb_get_username(newpwd), &result, attr_list );
1952 0 : TALLOC_FREE( attr_list );
1953 0 : if (rc != LDAP_SUCCESS) {
1954 0 : return NT_STATUS_UNSUCCESSFUL;
1955 : }
1956 0 : pdb_set_backend_private_data(newpwd, result, NULL,
1957 : my_methods, PDB_CHANGED);
1958 0 : smbldap_talloc_autofree_ldapmsg(newpwd, result);
1959 : }
1960 :
1961 0 : if (ldap_count_entries(smbldap_get_ldap(ldap_state->smbldap_state),
1962 : result) == 0) {
1963 0 : DEBUG(0, ("ldapsam_update_sam_account: No user to modify!\n"));
1964 0 : return NT_STATUS_UNSUCCESSFUL;
1965 : }
1966 :
1967 0 : entry = ldap_first_entry(smbldap_get_ldap(ldap_state->smbldap_state),
1968 : result);
1969 0 : dn = smbldap_talloc_dn(talloc_tos(),
1970 : smbldap_get_ldap(ldap_state->smbldap_state),
1971 : entry);
1972 0 : if (!dn) {
1973 0 : return NT_STATUS_UNSUCCESSFUL;
1974 : }
1975 :
1976 0 : DEBUG(4, ("ldapsam_update_sam_account: user %s to be modified has dn: %s\n", pdb_get_username(newpwd), dn));
1977 :
1978 0 : if (!init_ldap_from_sam(ldap_state, entry, &mods, newpwd,
1979 : pdb_element_is_changed)) {
1980 0 : DEBUG(0, ("ldapsam_update_sam_account: init_ldap_from_sam failed!\n"));
1981 0 : TALLOC_FREE(dn);
1982 0 : if (mods != NULL)
1983 0 : ldap_mods_free(mods,True);
1984 0 : return NT_STATUS_UNSUCCESSFUL;
1985 : }
1986 :
1987 0 : if ((lp_ldap_passwd_sync() != LDAP_PASSWD_SYNC_ONLY)
1988 0 : && (mods == NULL)) {
1989 0 : DEBUG(4,("ldapsam_update_sam_account: mods is empty: nothing to update for user: %s\n",
1990 : pdb_get_username(newpwd)));
1991 0 : TALLOC_FREE(dn);
1992 0 : return NT_STATUS_OK;
1993 : }
1994 :
1995 0 : ret = ldapsam_modify_entry(my_methods,newpwd,dn,mods,LDAP_MOD_REPLACE, pdb_element_is_changed);
1996 :
1997 0 : if (mods != NULL) {
1998 0 : ldap_mods_free(mods,True);
1999 : }
2000 :
2001 0 : TALLOC_FREE(dn);
2002 :
2003 : /*
2004 : * We need to set the backend private data to NULL here. For example
2005 : * setuserinfo level 25 does a pdb_update_sam_account twice on the
2006 : * same one, and with the explicit delete / add logic for attribute
2007 : * values the second time we would use the wrong "old" value which
2008 : * does not exist in LDAP anymore. Thus the LDAP server would refuse
2009 : * the update.
2010 : * The existing LDAPMessage is still being auto-freed by the
2011 : * destructor.
2012 : */
2013 0 : pdb_set_backend_private_data(newpwd, NULL, NULL, my_methods,
2014 : PDB_CHANGED);
2015 :
2016 0 : if (!NT_STATUS_IS_OK(ret)) {
2017 0 : return ret;
2018 : }
2019 :
2020 0 : DEBUG(2, ("ldapsam_update_sam_account: successfully modified uid = %s in the LDAP database\n",
2021 : pdb_get_username(newpwd)));
2022 0 : return NT_STATUS_OK;
2023 : }
2024 :
2025 : /***************************************************************************
2026 : Renames a struct samu
2027 : - The "rename user script" has full responsibility for changing everything
2028 : ***************************************************************************/
2029 :
2030 : static NTSTATUS ldapsam_del_groupmem(struct pdb_methods *my_methods,
2031 : TALLOC_CTX *tmp_ctx,
2032 : uint32_t group_rid,
2033 : uint32_t member_rid);
2034 :
2035 : static NTSTATUS ldapsam_enum_group_memberships(struct pdb_methods *methods,
2036 : TALLOC_CTX *mem_ctx,
2037 : struct samu *user,
2038 : struct dom_sid **pp_sids,
2039 : gid_t **pp_gids,
2040 : uint32_t *p_num_groups);
2041 :
2042 0 : static NTSTATUS ldapsam_rename_sam_account(struct pdb_methods *my_methods,
2043 : struct samu *old_acct,
2044 : const char *newname)
2045 : {
2046 0 : const struct loadparm_substitution *lp_sub =
2047 0 : loadparm_s3_global_substitution();
2048 0 : const char *oldname;
2049 0 : int rc;
2050 0 : char *rename_script = NULL;
2051 0 : fstring oldname_lower, newname_lower;
2052 :
2053 0 : if (!old_acct) {
2054 0 : DEBUG(0, ("ldapsam_rename_sam_account: old_acct was NULL!\n"));
2055 0 : return NT_STATUS_INVALID_PARAMETER;
2056 : }
2057 0 : if (!newname) {
2058 0 : DEBUG(0, ("ldapsam_rename_sam_account: newname was NULL!\n"));
2059 0 : return NT_STATUS_INVALID_PARAMETER;
2060 : }
2061 :
2062 0 : oldname = pdb_get_username(old_acct);
2063 :
2064 : /* rename the posix user */
2065 0 : rename_script = lp_rename_user_script(talloc_tos(), lp_sub);
2066 0 : if (rename_script == NULL) {
2067 0 : return NT_STATUS_NO_MEMORY;
2068 : }
2069 :
2070 0 : if (!(*rename_script)) {
2071 0 : TALLOC_FREE(rename_script);
2072 0 : return NT_STATUS_ACCESS_DENIED;
2073 : }
2074 :
2075 0 : DEBUG (3, ("ldapsam_rename_sam_account: Renaming user %s to %s.\n",
2076 : oldname, newname));
2077 :
2078 : /* We have to allow the account name to end with a '$'.
2079 : Also, follow the semantics in _samr_create_user() and lower case the
2080 : posix name but preserve the case in passdb */
2081 :
2082 0 : fstrcpy( oldname_lower, oldname );
2083 0 : if (!strlower_m( oldname_lower )) {
2084 0 : return NT_STATUS_INVALID_PARAMETER;
2085 : }
2086 0 : fstrcpy( newname_lower, newname );
2087 0 : if (!strlower_m( newname_lower )) {
2088 0 : return NT_STATUS_INVALID_PARAMETER;
2089 : }
2090 :
2091 0 : rename_script = realloc_string_sub2(rename_script,
2092 : "%unew",
2093 : newname_lower,
2094 : true,
2095 : true);
2096 0 : if (!rename_script) {
2097 0 : return NT_STATUS_NO_MEMORY;
2098 : }
2099 0 : rename_script = realloc_string_sub2(rename_script,
2100 : "%uold",
2101 : oldname_lower,
2102 : true,
2103 : true);
2104 0 : rc = smbrun(rename_script, NULL, NULL);
2105 :
2106 0 : DEBUG(rc ? 0 : 3,("Running the command `%s' gave %d\n",
2107 : rename_script, rc));
2108 :
2109 0 : TALLOC_FREE(rename_script);
2110 :
2111 0 : if (rc == 0) {
2112 0 : smb_nscd_flush_user_cache();
2113 : }
2114 :
2115 0 : if (rc)
2116 0 : return NT_STATUS_UNSUCCESSFUL;
2117 :
2118 0 : return NT_STATUS_OK;
2119 : }
2120 :
2121 : /**********************************************************************
2122 : Add struct samu to LDAP.
2123 : *********************************************************************/
2124 :
2125 0 : static NTSTATUS ldapsam_add_sam_account(struct pdb_methods *my_methods, struct samu * newpwd)
2126 : {
2127 0 : struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
2128 0 : int rc;
2129 0 : LDAPMessage *result = NULL;
2130 0 : LDAPMessage *entry = NULL;
2131 0 : LDAPMod **mods = NULL;
2132 0 : int ldap_op = LDAP_MOD_REPLACE;
2133 0 : uint32_t num_result;
2134 0 : const char **attr_list;
2135 0 : char *escape_user = NULL;
2136 0 : const char *username = pdb_get_username(newpwd);
2137 0 : const struct dom_sid *sid = pdb_get_user_sid(newpwd);
2138 0 : char *filter = NULL;
2139 0 : char *dn = NULL;
2140 0 : NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
2141 0 : TALLOC_CTX *ctx = talloc_init("ldapsam_add_sam_account");
2142 :
2143 0 : if (!ctx) {
2144 0 : return NT_STATUS_NO_MEMORY;
2145 : }
2146 :
2147 0 : if (!username || !*username) {
2148 0 : DEBUG(0, ("ldapsam_add_sam_account: Cannot add user without a username!\n"));
2149 0 : status = NT_STATUS_INVALID_PARAMETER;
2150 0 : goto fn_exit;
2151 : }
2152 :
2153 : /* free this list after the second search or in case we exit on failure */
2154 0 : attr_list = get_userattr_list(ctx, ldap_state->schema_ver);
2155 :
2156 0 : rc = ldapsam_search_suffix_by_name (ldap_state, username, &result, attr_list);
2157 :
2158 0 : if (rc != LDAP_SUCCESS) {
2159 0 : goto fn_exit;
2160 : }
2161 :
2162 0 : if (ldap_count_entries(smbldap_get_ldap(ldap_state->smbldap_state),
2163 : result) != 0) {
2164 0 : DEBUG(0,("ldapsam_add_sam_account: User '%s' already in the base, with samba attributes\n",
2165 : username));
2166 0 : goto fn_exit;
2167 : }
2168 0 : ldap_msgfree(result);
2169 0 : result = NULL;
2170 :
2171 0 : if (pdb_element_is_set_or_changed(newpwd, PDB_USERSID)) {
2172 0 : rc = ldapsam_get_ldap_user_by_sid(ldap_state,
2173 : sid, &result);
2174 0 : if (rc == LDAP_SUCCESS) {
2175 0 : if (ldap_count_entries(
2176 : smbldap_get_ldap(
2177 : ldap_state->smbldap_state),
2178 : result) != 0) {
2179 0 : struct dom_sid_buf buf;
2180 0 : DEBUG(0,("ldapsam_add_sam_account: SID '%s' "
2181 : "already in the base, with samba "
2182 : "attributes\n",
2183 : dom_sid_str_buf(sid, &buf)));
2184 0 : goto fn_exit;
2185 : }
2186 0 : ldap_msgfree(result);
2187 0 : result = NULL;
2188 : }
2189 : }
2190 :
2191 : /* does the entry already exist but without a samba attributes?
2192 : we need to return the samba attributes here */
2193 :
2194 0 : escape_user = escape_ldap_string(talloc_tos(), username);
2195 0 : filter = talloc_strdup(attr_list, "(uid=%u)");
2196 0 : if (!filter) {
2197 0 : status = NT_STATUS_NO_MEMORY;
2198 0 : goto fn_exit;
2199 : }
2200 0 : filter = talloc_all_string_sub(attr_list, filter, "%u", escape_user);
2201 0 : TALLOC_FREE(escape_user);
2202 0 : if (!filter) {
2203 0 : status = NT_STATUS_NO_MEMORY;
2204 0 : goto fn_exit;
2205 : }
2206 :
2207 0 : rc = smbldap_search_suffix(ldap_state->smbldap_state,
2208 : filter, attr_list, &result);
2209 0 : if ( rc != LDAP_SUCCESS ) {
2210 0 : goto fn_exit;
2211 : }
2212 :
2213 0 : num_result = ldap_count_entries(
2214 : smbldap_get_ldap(ldap_state->smbldap_state), result);
2215 :
2216 0 : if (num_result > 1) {
2217 0 : DEBUG (0, ("ldapsam_add_sam_account: More than one user with that uid exists: bailing out!\n"));
2218 0 : goto fn_exit;
2219 : }
2220 :
2221 : /* Check if we need to update an existing entry */
2222 0 : if (num_result == 1) {
2223 0 : DEBUG(3,("ldapsam_add_sam_account: User exists without samba attributes: adding them\n"));
2224 0 : ldap_op = LDAP_MOD_REPLACE;
2225 0 : entry = ldap_first_entry(
2226 : smbldap_get_ldap(ldap_state->smbldap_state), result);
2227 0 : dn = smbldap_talloc_dn(
2228 : ctx, smbldap_get_ldap(ldap_state->smbldap_state),
2229 : entry);
2230 0 : if (!dn) {
2231 0 : status = NT_STATUS_NO_MEMORY;
2232 0 : goto fn_exit;
2233 : }
2234 :
2235 0 : } else if (ldap_state->schema_ver == SCHEMAVER_SAMBASAMACCOUNT) {
2236 :
2237 0 : struct dom_sid_buf buf;
2238 :
2239 : /* There might be a SID for this account already - say an idmap entry */
2240 :
2241 0 : filter = talloc_asprintf(ctx,
2242 : "(&(%s=%s)(|(objectClass=%s)(objectClass=%s)))",
2243 : get_userattr_key2string(ldap_state->schema_ver,
2244 : LDAP_ATTR_USER_SID),
2245 : dom_sid_str_buf(sid, &buf),
2246 : LDAP_OBJ_IDMAP_ENTRY,
2247 : LDAP_OBJ_SID_ENTRY);
2248 0 : if (!filter) {
2249 0 : status = NT_STATUS_NO_MEMORY;
2250 0 : goto fn_exit;
2251 : }
2252 :
2253 : /* free old result before doing a new search */
2254 0 : if (result != NULL) {
2255 0 : ldap_msgfree(result);
2256 0 : result = NULL;
2257 : }
2258 0 : rc = smbldap_search_suffix(ldap_state->smbldap_state,
2259 : filter, attr_list, &result);
2260 :
2261 0 : if ( rc != LDAP_SUCCESS ) {
2262 0 : goto fn_exit;
2263 : }
2264 :
2265 0 : num_result = ldap_count_entries(
2266 : smbldap_get_ldap(ldap_state->smbldap_state), result);
2267 :
2268 0 : if (num_result > 1) {
2269 0 : DEBUG (0, ("ldapsam_add_sam_account: More than one user with specified Sid exists: bailing out!\n"));
2270 0 : goto fn_exit;
2271 : }
2272 :
2273 : /* Check if we need to update an existing entry */
2274 0 : if (num_result == 1) {
2275 :
2276 0 : DEBUG(3,("ldapsam_add_sam_account: User exists without samba attributes: adding them\n"));
2277 0 : ldap_op = LDAP_MOD_REPLACE;
2278 0 : entry = ldap_first_entry (
2279 : smbldap_get_ldap(ldap_state->smbldap_state),
2280 : result);
2281 0 : dn = smbldap_talloc_dn (
2282 : ctx,
2283 : smbldap_get_ldap(ldap_state->smbldap_state),
2284 : entry);
2285 0 : if (!dn) {
2286 0 : status = NT_STATUS_NO_MEMORY;
2287 0 : goto fn_exit;
2288 : }
2289 : }
2290 : }
2291 :
2292 0 : if (num_result == 0) {
2293 0 : char *escape_username;
2294 : /* Check if we need to add an entry */
2295 0 : DEBUG(3,("ldapsam_add_sam_account: Adding new user\n"));
2296 0 : ldap_op = LDAP_MOD_ADD;
2297 :
2298 0 : escape_username = escape_rdn_val_string_alloc(username);
2299 0 : if (!escape_username) {
2300 0 : status = NT_STATUS_NO_MEMORY;
2301 0 : goto fn_exit;
2302 : }
2303 :
2304 0 : if (username[strlen(username)-1] == '$') {
2305 0 : dn = talloc_asprintf(ctx,
2306 : "uid=%s,%s",
2307 : escape_username,
2308 : lp_ldap_machine_suffix(talloc_tos()));
2309 : } else {
2310 0 : dn = talloc_asprintf(ctx,
2311 : "uid=%s,%s",
2312 : escape_username,
2313 : lp_ldap_user_suffix(talloc_tos()));
2314 : }
2315 :
2316 0 : SAFE_FREE(escape_username);
2317 0 : if (!dn) {
2318 0 : status = NT_STATUS_NO_MEMORY;
2319 0 : goto fn_exit;
2320 : }
2321 : }
2322 :
2323 0 : if (!init_ldap_from_sam(ldap_state, entry, &mods, newpwd,
2324 : pdb_element_is_set_or_changed)) {
2325 0 : DEBUG(0, ("ldapsam_add_sam_account: init_ldap_from_sam failed!\n"));
2326 0 : if (mods != NULL) {
2327 0 : ldap_mods_free(mods, true);
2328 : }
2329 0 : goto fn_exit;
2330 : }
2331 :
2332 0 : if (mods == NULL) {
2333 0 : DEBUG(0,("ldapsam_add_sam_account: mods is empty: nothing to add for user: %s\n",pdb_get_username(newpwd)));
2334 0 : goto fn_exit;
2335 : }
2336 0 : switch ( ldap_state->schema_ver ) {
2337 0 : case SCHEMAVER_SAMBASAMACCOUNT:
2338 0 : smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectclass", LDAP_OBJ_SAMBASAMACCOUNT);
2339 0 : break;
2340 0 : default:
2341 0 : DEBUG(0,("ldapsam_add_sam_account: invalid schema version specified\n"));
2342 0 : break;
2343 : }
2344 :
2345 0 : status = ldapsam_modify_entry(my_methods,newpwd,dn,mods,ldap_op, pdb_element_is_set_or_changed);
2346 0 : if (!NT_STATUS_IS_OK(status)) {
2347 0 : DEBUG(0,("ldapsam_add_sam_account: failed to modify/add user with uid = %s (dn = %s)\n",
2348 : pdb_get_username(newpwd),dn));
2349 0 : ldap_mods_free(mods, true);
2350 0 : goto fn_exit;
2351 : }
2352 :
2353 0 : DEBUG(2,("ldapsam_add_sam_account: added: uid == %s in the LDAP database\n", pdb_get_username(newpwd)));
2354 0 : ldap_mods_free(mods, true);
2355 :
2356 0 : status = NT_STATUS_OK;
2357 :
2358 0 : fn_exit:
2359 :
2360 0 : TALLOC_FREE(ctx);
2361 0 : if (result) {
2362 0 : ldap_msgfree(result);
2363 : }
2364 0 : return status;
2365 : }
2366 :
2367 : /**********************************************************************
2368 : *********************************************************************/
2369 :
2370 0 : static int ldapsam_search_one_group (struct ldapsam_privates *ldap_state,
2371 : const char *filter,
2372 : LDAPMessage ** result)
2373 : {
2374 0 : int scope = LDAP_SCOPE_SUBTREE;
2375 0 : int rc;
2376 0 : const char **attr_list;
2377 :
2378 0 : attr_list = get_attr_list(NULL, groupmap_attr_list);
2379 0 : rc = smbldap_search(ldap_state->smbldap_state,
2380 : lp_ldap_suffix(), scope,
2381 : filter, attr_list, 0, result);
2382 0 : TALLOC_FREE(attr_list);
2383 :
2384 0 : return rc;
2385 : }
2386 :
2387 : /**********************************************************************
2388 : *********************************************************************/
2389 :
2390 0 : static bool init_group_from_ldap(struct ldapsam_privates *ldap_state,
2391 : GROUP_MAP *map, LDAPMessage *entry)
2392 : {
2393 0 : char *temp = NULL;
2394 0 : TALLOC_CTX *ctx = talloc_init("init_group_from_ldap");
2395 :
2396 0 : if (ldap_state == NULL || map == NULL || entry == NULL ||
2397 0 : smbldap_get_ldap(ldap_state->smbldap_state) == NULL) {
2398 0 : DEBUG(0, ("init_group_from_ldap: NULL parameters found!\n"));
2399 0 : TALLOC_FREE(ctx);
2400 0 : return false;
2401 : }
2402 :
2403 0 : temp = smbldap_talloc_single_attribute(
2404 : smbldap_get_ldap(ldap_state->smbldap_state),
2405 : entry,
2406 : get_attr_key2string(groupmap_attr_list,
2407 : LDAP_ATTR_GIDNUMBER),
2408 : ctx);
2409 0 : if (!temp) {
2410 0 : DEBUG(0, ("init_group_from_ldap: Mandatory attribute %s not found\n",
2411 : get_attr_key2string( groupmap_attr_list, LDAP_ATTR_GIDNUMBER)));
2412 0 : TALLOC_FREE(ctx);
2413 0 : return false;
2414 : }
2415 0 : DEBUG(2, ("init_group_from_ldap: Entry found for group: %s\n", temp));
2416 :
2417 0 : map->gid = (gid_t)atol(temp);
2418 :
2419 0 : TALLOC_FREE(temp);
2420 0 : temp = smbldap_talloc_single_attribute(
2421 : smbldap_get_ldap(ldap_state->smbldap_state),
2422 : entry,
2423 : get_attr_key2string(groupmap_attr_list,
2424 : LDAP_ATTR_GROUP_SID),
2425 : ctx);
2426 0 : if (!temp) {
2427 0 : DEBUG(0, ("init_group_from_ldap: Mandatory attribute %s not found\n",
2428 : get_attr_key2string( groupmap_attr_list, LDAP_ATTR_GROUP_SID)));
2429 0 : TALLOC_FREE(ctx);
2430 0 : return false;
2431 : }
2432 :
2433 0 : if (!string_to_sid(&map->sid, temp)) {
2434 0 : DEBUG(1, ("SID string [%s] could not be read as a valid SID\n", temp));
2435 0 : TALLOC_FREE(ctx);
2436 0 : return false;
2437 : }
2438 :
2439 0 : TALLOC_FREE(temp);
2440 0 : temp = smbldap_talloc_single_attribute(
2441 : smbldap_get_ldap(ldap_state->smbldap_state),
2442 : entry,
2443 : get_attr_key2string(groupmap_attr_list,
2444 : LDAP_ATTR_GROUP_TYPE),
2445 : ctx);
2446 0 : if (!temp) {
2447 0 : DEBUG(0, ("init_group_from_ldap: Mandatory attribute %s not found\n",
2448 : get_attr_key2string( groupmap_attr_list, LDAP_ATTR_GROUP_TYPE)));
2449 0 : TALLOC_FREE(ctx);
2450 0 : return false;
2451 : }
2452 0 : map->sid_name_use = (enum lsa_SidType)atol(temp);
2453 :
2454 0 : if ((map->sid_name_use < SID_NAME_USER) ||
2455 0 : (map->sid_name_use > SID_NAME_UNKNOWN)) {
2456 0 : DEBUG(0, ("init_group_from_ldap: Unknown Group type: %d\n", map->sid_name_use));
2457 0 : TALLOC_FREE(ctx);
2458 0 : return false;
2459 : }
2460 :
2461 0 : TALLOC_FREE(temp);
2462 0 : temp = smbldap_talloc_single_attribute(
2463 : smbldap_get_ldap(ldap_state->smbldap_state),
2464 : entry,
2465 : get_attr_key2string(groupmap_attr_list,
2466 : LDAP_ATTR_DISPLAY_NAME),
2467 : ctx);
2468 0 : if (!temp) {
2469 0 : temp = smbldap_talloc_single_attribute(
2470 : smbldap_get_ldap(ldap_state->smbldap_state),
2471 : entry,
2472 : get_attr_key2string(groupmap_attr_list,
2473 : LDAP_ATTR_CN),
2474 : ctx);
2475 0 : if (!temp) {
2476 0 : DEBUG(0, ("init_group_from_ldap: Attributes cn not found either \
2477 : for gidNumber(%lu)\n",(unsigned long)map->gid));
2478 0 : TALLOC_FREE(ctx);
2479 0 : return false;
2480 : }
2481 : }
2482 0 : map->nt_name = talloc_strdup(map, temp);
2483 0 : if (!map->nt_name) {
2484 0 : TALLOC_FREE(ctx);
2485 0 : return false;
2486 : }
2487 :
2488 0 : TALLOC_FREE(temp);
2489 0 : temp = smbldap_talloc_single_attribute(
2490 : smbldap_get_ldap(ldap_state->smbldap_state),
2491 : entry,
2492 : get_attr_key2string(groupmap_attr_list,
2493 : LDAP_ATTR_DESC),
2494 : ctx);
2495 0 : if (!temp) {
2496 0 : temp = talloc_strdup(ctx, "");
2497 0 : if (!temp) {
2498 0 : TALLOC_FREE(ctx);
2499 0 : return false;
2500 : }
2501 : }
2502 0 : map->comment = talloc_strdup(map, temp);
2503 0 : if (!map->comment) {
2504 0 : TALLOC_FREE(ctx);
2505 0 : return false;
2506 : }
2507 :
2508 0 : if (lp_parm_bool(-1, "ldapsam", "trusted", false)) {
2509 0 : struct unixid id;
2510 0 : id.id = map->gid;
2511 0 : id.type = ID_TYPE_GID;
2512 :
2513 0 : idmap_cache_set_sid2unixid(&map->sid, &id);
2514 : }
2515 :
2516 0 : TALLOC_FREE(ctx);
2517 0 : return true;
2518 : }
2519 :
2520 : /**********************************************************************
2521 : *********************************************************************/
2522 :
2523 0 : static NTSTATUS ldapsam_getgroup(struct pdb_methods *methods,
2524 : const char *filter,
2525 : GROUP_MAP *map)
2526 : {
2527 0 : struct ldapsam_privates *ldap_state =
2528 : (struct ldapsam_privates *)methods->private_data;
2529 0 : LDAPMessage *result = NULL;
2530 0 : LDAPMessage *entry = NULL;
2531 0 : int count;
2532 :
2533 0 : if (ldapsam_search_one_group(ldap_state, filter, &result)
2534 : != LDAP_SUCCESS) {
2535 0 : return NT_STATUS_NO_SUCH_GROUP;
2536 : }
2537 :
2538 0 : count = ldap_count_entries(priv2ld(ldap_state), result);
2539 :
2540 0 : if (count < 1) {
2541 0 : DEBUG(4, ("ldapsam_getgroup: Did not find group, filter was "
2542 : "%s\n", filter));
2543 0 : ldap_msgfree(result);
2544 0 : return NT_STATUS_NO_SUCH_GROUP;
2545 : }
2546 :
2547 0 : if (count > 1) {
2548 0 : DEBUG(1, ("ldapsam_getgroup: Duplicate entries for filter %s: "
2549 : "count=%d\n", filter, count));
2550 0 : ldap_msgfree(result);
2551 0 : return NT_STATUS_NO_SUCH_GROUP;
2552 : }
2553 :
2554 0 : entry = ldap_first_entry(priv2ld(ldap_state), result);
2555 :
2556 0 : if (!entry) {
2557 0 : ldap_msgfree(result);
2558 0 : return NT_STATUS_UNSUCCESSFUL;
2559 : }
2560 :
2561 0 : if (!init_group_from_ldap(ldap_state, map, entry)) {
2562 0 : DEBUG(1, ("ldapsam_getgroup: init_group_from_ldap failed for "
2563 : "group filter %s\n", filter));
2564 0 : ldap_msgfree(result);
2565 0 : return NT_STATUS_NO_SUCH_GROUP;
2566 : }
2567 :
2568 0 : ldap_msgfree(result);
2569 0 : return NT_STATUS_OK;
2570 : }
2571 :
2572 : /**********************************************************************
2573 : *********************************************************************/
2574 :
2575 0 : static NTSTATUS ldapsam_getgrsid(struct pdb_methods *methods, GROUP_MAP *map,
2576 : struct dom_sid sid)
2577 : {
2578 0 : char *filter = NULL;
2579 0 : NTSTATUS status;
2580 0 : struct dom_sid_buf tmp;
2581 :
2582 0 : if (asprintf(&filter, "(&(objectClass=%s)(%s=%s))",
2583 : LDAP_OBJ_GROUPMAP,
2584 : get_attr_key2string(groupmap_attr_list, LDAP_ATTR_GROUP_SID),
2585 : dom_sid_str_buf(&sid, &tmp)) < 0) {
2586 0 : return NT_STATUS_NO_MEMORY;
2587 : }
2588 :
2589 0 : status = ldapsam_getgroup(methods, filter, map);
2590 0 : SAFE_FREE(filter);
2591 0 : return status;
2592 : }
2593 :
2594 : /**********************************************************************
2595 : *********************************************************************/
2596 :
2597 0 : static NTSTATUS ldapsam_getgrgid(struct pdb_methods *methods, GROUP_MAP *map,
2598 : gid_t gid)
2599 : {
2600 0 : char *filter = NULL;
2601 0 : NTSTATUS status;
2602 :
2603 0 : if (asprintf(&filter, "(&(objectClass=%s)(%s=%lu))",
2604 : LDAP_OBJ_GROUPMAP,
2605 : get_attr_key2string(groupmap_attr_list, LDAP_ATTR_GIDNUMBER),
2606 : (unsigned long)gid) < 0) {
2607 0 : return NT_STATUS_NO_MEMORY;
2608 : }
2609 :
2610 0 : status = ldapsam_getgroup(methods, filter, map);
2611 0 : SAFE_FREE(filter);
2612 0 : return status;
2613 : }
2614 :
2615 : /**********************************************************************
2616 : *********************************************************************/
2617 :
2618 0 : static NTSTATUS ldapsam_getgrnam(struct pdb_methods *methods, GROUP_MAP *map,
2619 : const char *name)
2620 : {
2621 0 : char *filter = NULL;
2622 0 : char *escape_name = escape_ldap_string(talloc_tos(), name);
2623 0 : NTSTATUS status;
2624 :
2625 0 : if (!escape_name) {
2626 0 : return NT_STATUS_NO_MEMORY;
2627 : }
2628 :
2629 0 : if (asprintf(&filter, "(&(objectClass=%s)(|(%s=%s)(%s=%s)))",
2630 : LDAP_OBJ_GROUPMAP,
2631 : get_attr_key2string(groupmap_attr_list, LDAP_ATTR_DISPLAY_NAME), escape_name,
2632 : get_attr_key2string(groupmap_attr_list, LDAP_ATTR_CN),
2633 : escape_name) < 0) {
2634 0 : TALLOC_FREE(escape_name);
2635 0 : return NT_STATUS_NO_MEMORY;
2636 : }
2637 :
2638 0 : TALLOC_FREE(escape_name);
2639 0 : status = ldapsam_getgroup(methods, filter, map);
2640 0 : SAFE_FREE(filter);
2641 0 : return status;
2642 : }
2643 :
2644 0 : static bool ldapsam_extract_rid_from_entry(LDAP *ldap_struct,
2645 : LDAPMessage *entry,
2646 : const struct dom_sid *domain_sid,
2647 : uint32_t *rid)
2648 : {
2649 0 : fstring str;
2650 0 : struct dom_sid sid;
2651 :
2652 0 : if (!smbldap_get_single_attribute(ldap_struct, entry, "sambaSID",
2653 : str, sizeof(str)-1)) {
2654 0 : DEBUG(10, ("Could not find sambaSID attribute\n"));
2655 0 : return False;
2656 : }
2657 :
2658 0 : if (!string_to_sid(&sid, str)) {
2659 0 : DEBUG(10, ("Could not convert string %s to sid\n", str));
2660 0 : return False;
2661 : }
2662 :
2663 0 : if (dom_sid_compare_domain(&sid, domain_sid) != 0) {
2664 0 : struct dom_sid_buf buf;
2665 0 : DEBUG(10, ("SID %s is not in expected domain %s\n",
2666 : str,
2667 : dom_sid_str_buf(domain_sid, &buf)));
2668 0 : return False;
2669 : }
2670 :
2671 0 : if (!sid_peek_rid(&sid, rid)) {
2672 0 : DEBUG(10, ("Could not peek into RID\n"));
2673 0 : return False;
2674 : }
2675 :
2676 0 : return True;
2677 : }
2678 :
2679 0 : static NTSTATUS ldapsam_enum_group_members(struct pdb_methods *methods,
2680 : TALLOC_CTX *mem_ctx,
2681 : const struct dom_sid *group,
2682 : uint32_t **pp_member_rids,
2683 : size_t *p_num_members)
2684 : {
2685 0 : struct ldapsam_privates *ldap_state =
2686 : (struct ldapsam_privates *)methods->private_data;
2687 0 : struct smbldap_state *conn = ldap_state->smbldap_state;
2688 0 : const char *id_attrs[] = { "memberUid", "gidNumber", NULL };
2689 0 : const char *sid_attrs[] = { "sambaSID", NULL };
2690 0 : NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
2691 0 : LDAPMessage *result = NULL;
2692 0 : LDAPMessage *entry;
2693 0 : char *filter;
2694 0 : char **values = NULL;
2695 0 : char **memberuid;
2696 0 : char *gidstr;
2697 0 : int rc, count;
2698 0 : struct dom_sid_buf buf;
2699 :
2700 0 : *pp_member_rids = NULL;
2701 0 : *p_num_members = 0;
2702 :
2703 0 : filter = talloc_asprintf(mem_ctx,
2704 : "(&(objectClass="LDAP_OBJ_POSIXGROUP")"
2705 : "(objectClass="LDAP_OBJ_GROUPMAP")"
2706 : "(sambaSID=%s))",
2707 : dom_sid_str_buf(group, &buf));
2708 0 : if (filter == NULL) {
2709 0 : ret = NT_STATUS_NO_MEMORY;
2710 0 : goto done;
2711 : }
2712 :
2713 0 : rc = smbldap_search(conn, lp_ldap_suffix(),
2714 : LDAP_SCOPE_SUBTREE, filter, id_attrs, 0,
2715 : &result);
2716 :
2717 0 : if (rc != LDAP_SUCCESS)
2718 0 : goto done;
2719 :
2720 0 : smbldap_talloc_autofree_ldapmsg(mem_ctx, result);
2721 :
2722 0 : count = ldap_count_entries(smbldap_get_ldap(conn), result);
2723 :
2724 0 : if (count > 1) {
2725 0 : DEBUG(1, ("Found more than one groupmap entry for %s\n",
2726 : dom_sid_str_buf(group, &buf)));
2727 0 : ret = NT_STATUS_INTERNAL_DB_CORRUPTION;
2728 0 : goto done;
2729 : }
2730 :
2731 0 : if (count == 0) {
2732 0 : ret = NT_STATUS_NO_SUCH_GROUP;
2733 0 : goto done;
2734 : }
2735 :
2736 0 : entry = ldap_first_entry(smbldap_get_ldap(conn), result);
2737 0 : if (entry == NULL)
2738 0 : goto done;
2739 :
2740 0 : gidstr = smbldap_talloc_single_attribute(priv2ld(ldap_state), entry, "gidNumber", mem_ctx);
2741 0 : if (!gidstr) {
2742 0 : DEBUG (0, ("ldapsam_enum_group_members: Unable to find the group's gid!\n"));
2743 0 : ret = NT_STATUS_INTERNAL_DB_CORRUPTION;
2744 0 : goto done;
2745 : }
2746 :
2747 0 : values = ldap_get_values(smbldap_get_ldap(conn), entry, "memberUid");
2748 :
2749 0 : if ((values != NULL) && (values[0] != NULL)) {
2750 :
2751 0 : filter = talloc_strdup(mem_ctx, "(&(objectClass="LDAP_OBJ_SAMBASAMACCOUNT")(|");
2752 :
2753 0 : for (memberuid = values; *memberuid != NULL; memberuid += 1) {
2754 0 : char *escape_memberuid;
2755 :
2756 0 : escape_memberuid = escape_ldap_string(talloc_tos(),
2757 : *memberuid);
2758 0 : if (escape_memberuid == NULL) {
2759 0 : ret = NT_STATUS_NO_MEMORY;
2760 0 : goto done;
2761 : }
2762 :
2763 0 : filter = talloc_asprintf_append_buffer(filter, "(uid=%s)", escape_memberuid);
2764 0 : TALLOC_FREE(escape_memberuid);
2765 0 : if (filter == NULL) {
2766 0 : ret = NT_STATUS_NO_MEMORY;
2767 0 : goto done;
2768 : }
2769 : }
2770 :
2771 0 : filter = talloc_asprintf_append_buffer(filter, "))");
2772 0 : if (filter == NULL) {
2773 0 : ret = NT_STATUS_NO_MEMORY;
2774 0 : goto done;
2775 : }
2776 :
2777 0 : rc = smbldap_search(conn, lp_ldap_suffix(),
2778 : LDAP_SCOPE_SUBTREE, filter, sid_attrs, 0,
2779 : &result);
2780 :
2781 0 : if (rc != LDAP_SUCCESS)
2782 0 : goto done;
2783 :
2784 0 : count = ldap_count_entries(smbldap_get_ldap(conn), result);
2785 0 : DEBUG(10,("ldapsam_enum_group_members: found %d accounts\n", count));
2786 :
2787 0 : smbldap_talloc_autofree_ldapmsg(mem_ctx, result);
2788 :
2789 0 : for (entry = ldap_first_entry(smbldap_get_ldap(conn), result);
2790 0 : entry != NULL;
2791 0 : entry = ldap_next_entry(smbldap_get_ldap(conn), entry))
2792 : {
2793 0 : char *sidstr;
2794 0 : struct dom_sid sid;
2795 0 : uint32_t rid;
2796 :
2797 0 : sidstr = smbldap_talloc_single_attribute(
2798 : smbldap_get_ldap(conn), entry, "sambaSID",
2799 : mem_ctx);
2800 0 : if (!sidstr) {
2801 0 : DEBUG(0, ("Severe DB error, %s can't miss the sambaSID"
2802 : "attribute\n", LDAP_OBJ_SAMBASAMACCOUNT));
2803 0 : ret = NT_STATUS_INTERNAL_DB_CORRUPTION;
2804 0 : goto done;
2805 : }
2806 :
2807 0 : if (!string_to_sid(&sid, sidstr))
2808 0 : goto done;
2809 :
2810 0 : if (!sid_check_is_in_our_sam(&sid)) {
2811 0 : DEBUG(0, ("Inconsistent SAM -- group member uid not "
2812 : "in our domain\n"));
2813 0 : ret = NT_STATUS_INTERNAL_DB_CORRUPTION;
2814 0 : goto done;
2815 : }
2816 :
2817 0 : sid_peek_rid(&sid, &rid);
2818 :
2819 0 : if (!add_rid_to_array_unique(mem_ctx, rid, pp_member_rids,
2820 : p_num_members)) {
2821 0 : ret = NT_STATUS_NO_MEMORY;
2822 0 : goto done;
2823 : }
2824 : }
2825 : }
2826 :
2827 0 : filter = talloc_asprintf(mem_ctx,
2828 : "(&(objectClass=%s)"
2829 : "(gidNumber=%s))",
2830 : LDAP_OBJ_SAMBASAMACCOUNT,
2831 : gidstr);
2832 :
2833 0 : rc = smbldap_search(conn, lp_ldap_suffix(),
2834 : LDAP_SCOPE_SUBTREE, filter, sid_attrs, 0,
2835 : &result);
2836 :
2837 0 : if (rc != LDAP_SUCCESS)
2838 0 : goto done;
2839 :
2840 0 : smbldap_talloc_autofree_ldapmsg(mem_ctx, result);
2841 :
2842 0 : for (entry = ldap_first_entry(smbldap_get_ldap(conn), result);
2843 0 : entry != NULL;
2844 0 : entry = ldap_next_entry(smbldap_get_ldap(conn), entry))
2845 : {
2846 0 : uint32_t rid;
2847 :
2848 0 : if (!ldapsam_extract_rid_from_entry(smbldap_get_ldap(conn),
2849 : entry,
2850 0 : get_global_sam_sid(),
2851 : &rid)) {
2852 0 : DEBUG(0, ("Severe DB error, %s can't miss the samba SID"
2853 : "attribute\n", LDAP_OBJ_SAMBASAMACCOUNT));
2854 0 : ret = NT_STATUS_INTERNAL_DB_CORRUPTION;
2855 0 : goto done;
2856 : }
2857 :
2858 0 : if (!add_rid_to_array_unique(mem_ctx, rid, pp_member_rids,
2859 : p_num_members)) {
2860 0 : ret = NT_STATUS_NO_MEMORY;
2861 0 : goto done;
2862 : }
2863 : }
2864 :
2865 0 : ret = NT_STATUS_OK;
2866 :
2867 0 : done:
2868 :
2869 0 : if (values)
2870 0 : ldap_value_free(values);
2871 :
2872 0 : return ret;
2873 : }
2874 :
2875 0 : static NTSTATUS ldapsam_enum_group_memberships(struct pdb_methods *methods,
2876 : TALLOC_CTX *mem_ctx,
2877 : struct samu *user,
2878 : struct dom_sid **pp_sids,
2879 : gid_t **pp_gids,
2880 : uint32_t *p_num_groups)
2881 : {
2882 0 : struct ldapsam_privates *ldap_state =
2883 : (struct ldapsam_privates *)methods->private_data;
2884 0 : struct smbldap_state *conn = ldap_state->smbldap_state;
2885 0 : char *filter;
2886 0 : const char *attrs[] = { "gidNumber", "sambaSID", NULL };
2887 0 : char *escape_name;
2888 0 : int rc, count;
2889 0 : LDAPMessage *result = NULL;
2890 0 : LDAPMessage *entry;
2891 0 : NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
2892 0 : uint32_t num_sids;
2893 0 : uint32_t num_gids;
2894 0 : char *gidstr;
2895 0 : gid_t primary_gid = -1;
2896 0 : int error = 0;
2897 :
2898 0 : *pp_sids = NULL;
2899 0 : num_sids = 0;
2900 :
2901 0 : if (pdb_get_username(user) == NULL) {
2902 0 : return NT_STATUS_INVALID_PARAMETER;
2903 : }
2904 :
2905 0 : escape_name = escape_ldap_string(talloc_tos(), pdb_get_username(user));
2906 0 : if (escape_name == NULL)
2907 0 : return NT_STATUS_NO_MEMORY;
2908 :
2909 0 : if (user->unix_pw) {
2910 0 : primary_gid = user->unix_pw->pw_gid;
2911 : } else {
2912 : /* retrieve the users primary gid */
2913 0 : filter = talloc_asprintf(mem_ctx,
2914 : "(&(objectClass="LDAP_OBJ_SAMBASAMACCOUNT")(uid=%s))",
2915 : escape_name);
2916 0 : if (filter == NULL) {
2917 0 : ret = NT_STATUS_NO_MEMORY;
2918 0 : goto done;
2919 : }
2920 :
2921 0 : rc = smbldap_search(conn, lp_ldap_suffix(),
2922 : LDAP_SCOPE_SUBTREE, filter, attrs, 0, &result);
2923 :
2924 0 : if (rc != LDAP_SUCCESS)
2925 0 : goto done;
2926 :
2927 0 : smbldap_talloc_autofree_ldapmsg(mem_ctx, result);
2928 :
2929 0 : count = ldap_count_entries(priv2ld(ldap_state), result);
2930 :
2931 0 : switch (count) {
2932 0 : case 0:
2933 0 : DEBUG(1, ("User account [%s] not found!\n", pdb_get_username(user)));
2934 0 : ret = NT_STATUS_NO_SUCH_USER;
2935 0 : goto done;
2936 0 : case 1:
2937 0 : entry = ldap_first_entry(priv2ld(ldap_state), result);
2938 :
2939 0 : gidstr = smbldap_talloc_single_attribute(priv2ld(ldap_state), entry, "gidNumber", mem_ctx);
2940 0 : if (!gidstr) {
2941 0 : DEBUG (1, ("Unable to find the member's gid!\n"));
2942 0 : ret = NT_STATUS_INTERNAL_DB_CORRUPTION;
2943 0 : goto done;
2944 : }
2945 0 : primary_gid = smb_strtoul(gidstr,
2946 : NULL,
2947 : 10,
2948 : &error,
2949 : SMB_STR_STANDARD);
2950 0 : if (error != 0) {
2951 0 : DBG_ERR("Failed to convert GID\n");
2952 0 : goto done;
2953 : }
2954 0 : break;
2955 0 : default:
2956 0 : DEBUG(1, ("found more than one account with the same user name ?!\n"));
2957 0 : ret = NT_STATUS_INTERNAL_DB_CORRUPTION;
2958 0 : goto done;
2959 : }
2960 : }
2961 :
2962 0 : filter = talloc_asprintf(mem_ctx,
2963 : "(&(objectClass="LDAP_OBJ_POSIXGROUP")(|(memberUid=%s)(gidNumber=%u)))",
2964 : escape_name, (unsigned int)primary_gid);
2965 0 : if (filter == NULL) {
2966 0 : ret = NT_STATUS_NO_MEMORY;
2967 0 : goto done;
2968 : }
2969 :
2970 0 : rc = smbldap_search(conn, lp_ldap_suffix(),
2971 : LDAP_SCOPE_SUBTREE, filter, attrs, 0, &result);
2972 :
2973 0 : if (rc != LDAP_SUCCESS)
2974 0 : goto done;
2975 :
2976 0 : smbldap_talloc_autofree_ldapmsg(mem_ctx, result);
2977 :
2978 0 : num_gids = 0;
2979 0 : *pp_gids = NULL;
2980 :
2981 0 : num_sids = 0;
2982 0 : *pp_sids = NULL;
2983 :
2984 : /* We need to add the primary group as the first gid/sid */
2985 :
2986 0 : if (!add_gid_to_array_unique(mem_ctx, primary_gid, pp_gids, &num_gids)) {
2987 0 : ret = NT_STATUS_NO_MEMORY;
2988 0 : goto done;
2989 : }
2990 :
2991 : /* This sid will be replaced later */
2992 :
2993 0 : ret = add_sid_to_array_unique(mem_ctx, &global_sid_NULL, pp_sids,
2994 : &num_sids);
2995 0 : if (!NT_STATUS_IS_OK(ret)) {
2996 0 : goto done;
2997 : }
2998 :
2999 0 : for (entry = ldap_first_entry(smbldap_get_ldap(conn), result);
3000 0 : entry != NULL;
3001 0 : entry = ldap_next_entry(smbldap_get_ldap(conn), entry))
3002 : {
3003 0 : fstring str;
3004 0 : struct dom_sid sid;
3005 0 : gid_t gid;
3006 :
3007 0 : if (!smbldap_get_single_attribute(smbldap_get_ldap(conn),
3008 : entry, "sambaSID",
3009 : str, sizeof(str)-1))
3010 0 : continue;
3011 :
3012 0 : if (!string_to_sid(&sid, str))
3013 0 : goto done;
3014 :
3015 0 : if (!smbldap_get_single_attribute(smbldap_get_ldap(conn),
3016 : entry, "gidNumber",
3017 : str, sizeof(str)-1))
3018 0 : continue;
3019 :
3020 0 : gid = smb_strtoul(str, NULL, 10, &error, SMB_STR_FULL_STR_CONV);
3021 :
3022 0 : if (error != 0) {
3023 0 : goto done;
3024 : }
3025 :
3026 0 : if (gid == primary_gid) {
3027 0 : sid_copy(&(*pp_sids)[0], &sid);
3028 : } else {
3029 0 : if (!add_gid_to_array_unique(mem_ctx, gid, pp_gids,
3030 : &num_gids)) {
3031 0 : ret = NT_STATUS_NO_MEMORY;
3032 0 : goto done;
3033 : }
3034 0 : ret = add_sid_to_array_unique(mem_ctx, &sid, pp_sids,
3035 : &num_sids);
3036 0 : if (!NT_STATUS_IS_OK(ret)) {
3037 0 : goto done;
3038 : }
3039 : }
3040 : }
3041 :
3042 0 : if (dom_sid_compare(&global_sid_NULL, &(*pp_sids)[0]) == 0) {
3043 0 : DEBUG(3, ("primary group of [%s] not found\n",
3044 : pdb_get_username(user)));
3045 0 : ret = NT_STATUS_INTERNAL_DB_CORRUPTION;
3046 0 : goto done;
3047 : }
3048 :
3049 0 : *p_num_groups = num_sids;
3050 :
3051 0 : ret = NT_STATUS_OK;
3052 :
3053 0 : done:
3054 :
3055 0 : TALLOC_FREE(escape_name);
3056 0 : return ret;
3057 : }
3058 :
3059 : /**********************************************************************
3060 : * Augment a posixGroup object with a sambaGroupMapping domgroup
3061 : *********************************************************************/
3062 :
3063 0 : static NTSTATUS ldapsam_map_posixgroup(TALLOC_CTX *mem_ctx,
3064 : struct ldapsam_privates *ldap_state,
3065 : GROUP_MAP *map)
3066 : {
3067 0 : const char *filter, *dn;
3068 0 : LDAPMessage *msg, *entry;
3069 0 : LDAPMod **mods;
3070 0 : struct dom_sid_buf buf;
3071 0 : int rc;
3072 :
3073 0 : filter = talloc_asprintf(mem_ctx,
3074 : "(&(objectClass="LDAP_OBJ_POSIXGROUP")(gidNumber=%u))",
3075 0 : (unsigned int)map->gid);
3076 0 : if (filter == NULL) {
3077 0 : return NT_STATUS_NO_MEMORY;
3078 : }
3079 :
3080 0 : rc = smbldap_search_suffix(ldap_state->smbldap_state, filter,
3081 : get_attr_list(mem_ctx, groupmap_attr_list),
3082 : &msg);
3083 0 : smbldap_talloc_autofree_ldapmsg(mem_ctx, msg);
3084 :
3085 0 : if ((rc != LDAP_SUCCESS) ||
3086 0 : (ldap_count_entries(smbldap_get_ldap(ldap_state->smbldap_state),
3087 0 : msg) != 1) ||
3088 0 : ((entry = ldap_first_entry(
3089 : smbldap_get_ldap(ldap_state->smbldap_state),
3090 : msg)) == NULL)) {
3091 0 : return NT_STATUS_NO_SUCH_GROUP;
3092 : }
3093 :
3094 0 : dn = smbldap_talloc_dn(mem_ctx,
3095 : smbldap_get_ldap(ldap_state->smbldap_state),
3096 : entry);
3097 0 : if (dn == NULL) {
3098 0 : return NT_STATUS_NO_MEMORY;
3099 : }
3100 :
3101 0 : mods = NULL;
3102 0 : smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectClass",
3103 : LDAP_OBJ_GROUPMAP);
3104 0 : smbldap_make_mod(smbldap_get_ldap(ldap_state->smbldap_state), entry,
3105 : &mods, "sambaSid",
3106 0 : dom_sid_str_buf(&map->sid, &buf));
3107 0 : smbldap_make_mod(smbldap_get_ldap(ldap_state->smbldap_state), entry,
3108 : &mods, "sambaGroupType",
3109 0 : talloc_asprintf(mem_ctx, "%d", map->sid_name_use));
3110 0 : smbldap_make_mod(smbldap_get_ldap(ldap_state->smbldap_state), entry,
3111 : &mods, "displayName",
3112 0 : map->nt_name);
3113 0 : smbldap_make_mod(smbldap_get_ldap(ldap_state->smbldap_state), entry,
3114 : &mods, "description",
3115 0 : map->comment);
3116 0 : smbldap_talloc_autofree_ldapmod(mem_ctx, mods);
3117 :
3118 0 : rc = smbldap_modify(ldap_state->smbldap_state, dn, mods);
3119 0 : if (rc != LDAP_SUCCESS) {
3120 0 : return NT_STATUS_ACCESS_DENIED;
3121 : }
3122 :
3123 0 : return NT_STATUS_OK;
3124 : }
3125 :
3126 0 : static NTSTATUS ldapsam_add_group_mapping_entry(struct pdb_methods *methods,
3127 : GROUP_MAP *map)
3128 : {
3129 0 : struct ldapsam_privates *ldap_state =
3130 : (struct ldapsam_privates *)methods->private_data;
3131 0 : LDAPMessage *msg = NULL;
3132 0 : LDAPMod **mods = NULL;
3133 0 : const char *attrs[] = { NULL };
3134 0 : char *filter;
3135 :
3136 0 : char *dn;
3137 0 : TALLOC_CTX *mem_ctx;
3138 0 : NTSTATUS result;
3139 :
3140 0 : struct dom_sid sid;
3141 0 : struct dom_sid_buf buf;
3142 0 : struct unixid id;
3143 :
3144 0 : int rc;
3145 :
3146 0 : mem_ctx = talloc_new(NULL);
3147 0 : if (mem_ctx == NULL) {
3148 0 : DEBUG(0, ("talloc_new failed\n"));
3149 0 : return NT_STATUS_NO_MEMORY;
3150 : }
3151 :
3152 0 : filter = talloc_asprintf(mem_ctx, "(sambaSid=%s)",
3153 0 : dom_sid_str_buf(&map->sid, &buf));
3154 0 : if (filter == NULL) {
3155 0 : result = NT_STATUS_NO_MEMORY;
3156 0 : goto done;
3157 : }
3158 :
3159 0 : rc = smbldap_search(ldap_state->smbldap_state, lp_ldap_suffix(),
3160 : LDAP_SCOPE_SUBTREE, filter, attrs, True, &msg);
3161 0 : smbldap_talloc_autofree_ldapmsg(mem_ctx, msg);
3162 :
3163 0 : if ((rc == LDAP_SUCCESS) &&
3164 0 : (ldap_count_entries(smbldap_get_ldap(ldap_state->smbldap_state),
3165 : msg) > 0)) {
3166 :
3167 0 : DEBUG(3, ("SID %s already present in LDAP, refusing to add "
3168 : "group mapping entry\n",
3169 : dom_sid_str_buf(&map->sid, &buf)));
3170 0 : result = NT_STATUS_GROUP_EXISTS;
3171 0 : goto done;
3172 : }
3173 :
3174 0 : switch (map->sid_name_use) {
3175 :
3176 0 : case SID_NAME_DOM_GRP:
3177 : /* To map a domain group we need to have a posix group
3178 : to attach to. */
3179 0 : result = ldapsam_map_posixgroup(mem_ctx, ldap_state, map);
3180 0 : goto done;
3181 0 : break;
3182 :
3183 0 : case SID_NAME_ALIAS:
3184 0 : if (!sid_check_is_in_our_sam(&map->sid)
3185 0 : && !sid_check_is_in_builtin(&map->sid) )
3186 : {
3187 0 : DEBUG(3, ("Refusing to map sid %s as an alias, not in our domain\n",
3188 : dom_sid_str_buf(&map->sid, &buf)));
3189 0 : result = NT_STATUS_INVALID_PARAMETER;
3190 0 : goto done;
3191 : }
3192 0 : break;
3193 :
3194 0 : default:
3195 0 : DEBUG(3, ("Got invalid use '%s' for mapping\n",
3196 : sid_type_lookup(map->sid_name_use)));
3197 0 : result = NT_STATUS_INVALID_PARAMETER;
3198 0 : goto done;
3199 : }
3200 :
3201 : /* Domain groups have been mapped in a separate routine, we have to
3202 : * create an alias now */
3203 :
3204 0 : if (map->gid == -1) {
3205 0 : DEBUG(10, ("Refusing to map gid==-1\n"));
3206 0 : result = NT_STATUS_INVALID_PARAMETER;
3207 0 : goto done;
3208 : }
3209 :
3210 0 : id.id = map->gid;
3211 0 : id.type = ID_TYPE_GID;
3212 :
3213 0 : if (pdb_id_to_sid(&id, &sid)) {
3214 0 : DEBUG(3, ("Gid %u is already mapped to SID %s, refusing to "
3215 : "add\n",
3216 : (unsigned int)map->gid,
3217 : dom_sid_str_buf(&sid, &buf)));
3218 0 : result = NT_STATUS_GROUP_EXISTS;
3219 0 : goto done;
3220 : }
3221 :
3222 : /* Ok, enough checks done. It's still racy to go ahead now, but that's
3223 : * the best we can get out of LDAP. */
3224 :
3225 0 : dn = talloc_asprintf(mem_ctx, "sambaSid=%s,%s",
3226 0 : dom_sid_str_buf(&map->sid, &buf),
3227 : lp_ldap_group_suffix(talloc_tos()));
3228 0 : if (dn == NULL) {
3229 0 : result = NT_STATUS_NO_MEMORY;
3230 0 : goto done;
3231 : }
3232 :
3233 0 : mods = NULL;
3234 :
3235 0 : smbldap_make_mod(smbldap_get_ldap(ldap_state->smbldap_state), NULL,
3236 : &mods, "objectClass", LDAP_OBJ_SID_ENTRY);
3237 0 : smbldap_make_mod(smbldap_get_ldap(ldap_state->smbldap_state), NULL,
3238 : &mods, "objectClass", LDAP_OBJ_GROUPMAP);
3239 0 : smbldap_make_mod(smbldap_get_ldap(ldap_state->smbldap_state), NULL,
3240 : &mods, "sambaSid",
3241 0 : dom_sid_str_buf(&map->sid, &buf));
3242 0 : smbldap_make_mod(smbldap_get_ldap(ldap_state->smbldap_state), NULL,
3243 : &mods, "sambaGroupType",
3244 0 : talloc_asprintf(mem_ctx, "%d", map->sid_name_use));
3245 0 : smbldap_make_mod(smbldap_get_ldap(ldap_state->smbldap_state), NULL,
3246 : &mods, "displayName",
3247 0 : map->nt_name);
3248 0 : smbldap_make_mod(smbldap_get_ldap(ldap_state->smbldap_state), NULL,
3249 : &mods, "description",
3250 0 : map->comment);
3251 0 : smbldap_make_mod(smbldap_get_ldap(ldap_state->smbldap_state), NULL,
3252 : &mods, "gidNumber",
3253 0 : talloc_asprintf(mem_ctx, "%u",
3254 0 : (unsigned int)map->gid));
3255 0 : smbldap_talloc_autofree_ldapmod(mem_ctx, mods);
3256 :
3257 0 : rc = smbldap_add(ldap_state->smbldap_state, dn, mods);
3258 :
3259 0 : result = (rc == LDAP_SUCCESS) ?
3260 0 : NT_STATUS_OK : NT_STATUS_ACCESS_DENIED;
3261 :
3262 0 : done:
3263 0 : TALLOC_FREE(mem_ctx);
3264 0 : return result;
3265 : }
3266 :
3267 : /**********************************************************************
3268 : * Update a group mapping entry. We're quite strict about what can be changed:
3269 : * Only the description and displayname may be changed. It simply does not
3270 : * make any sense to change the SID, gid or the type in a mapping.
3271 : *********************************************************************/
3272 :
3273 0 : static NTSTATUS ldapsam_update_group_mapping_entry(struct pdb_methods *methods,
3274 : GROUP_MAP *map)
3275 : {
3276 0 : struct ldapsam_privates *ldap_state =
3277 : (struct ldapsam_privates *)methods->private_data;
3278 0 : int rc;
3279 0 : const char *filter, *dn;
3280 0 : LDAPMessage *msg = NULL;
3281 0 : LDAPMessage *entry = NULL;
3282 0 : LDAPMod **mods = NULL;
3283 0 : TALLOC_CTX *mem_ctx;
3284 0 : NTSTATUS result;
3285 0 : struct dom_sid_buf buf;
3286 :
3287 0 : mem_ctx = talloc_new(NULL);
3288 0 : if (mem_ctx == NULL) {
3289 0 : DEBUG(0, ("talloc_new failed\n"));
3290 0 : return NT_STATUS_NO_MEMORY;
3291 : }
3292 :
3293 : /* Make 100% sure that sid, gid and type are not changed by looking up
3294 : * exactly the values we're given in LDAP. */
3295 :
3296 0 : filter = talloc_asprintf(mem_ctx, "(&(objectClass="LDAP_OBJ_GROUPMAP")"
3297 : "(sambaSid=%s)(gidNumber=%u)"
3298 : "(sambaGroupType=%d))",
3299 0 : dom_sid_str_buf(&map->sid, &buf),
3300 0 : (unsigned int)map->gid, map->sid_name_use);
3301 0 : if (filter == NULL) {
3302 0 : result = NT_STATUS_NO_MEMORY;
3303 0 : goto done;
3304 : }
3305 :
3306 0 : rc = smbldap_search_suffix(ldap_state->smbldap_state, filter,
3307 : get_attr_list(mem_ctx, groupmap_attr_list),
3308 : &msg);
3309 0 : smbldap_talloc_autofree_ldapmsg(mem_ctx, msg);
3310 :
3311 0 : if ((rc != LDAP_SUCCESS) ||
3312 0 : (ldap_count_entries(smbldap_get_ldap(ldap_state->smbldap_state),
3313 0 : msg) != 1) ||
3314 0 : ((entry = ldap_first_entry(
3315 : smbldap_get_ldap(ldap_state->smbldap_state),
3316 : msg)) == NULL)) {
3317 0 : result = NT_STATUS_NO_SUCH_GROUP;
3318 0 : goto done;
3319 : }
3320 :
3321 0 : dn = smbldap_talloc_dn(
3322 : mem_ctx, smbldap_get_ldap(ldap_state->smbldap_state), entry);
3323 :
3324 0 : if (dn == NULL) {
3325 0 : result = NT_STATUS_NO_MEMORY;
3326 0 : goto done;
3327 : }
3328 :
3329 0 : mods = NULL;
3330 0 : smbldap_make_mod(smbldap_get_ldap(ldap_state->smbldap_state), entry,
3331 0 : &mods, "displayName", map->nt_name);
3332 0 : smbldap_make_mod(smbldap_get_ldap(ldap_state->smbldap_state), entry,
3333 0 : &mods, "description", map->comment);
3334 0 : smbldap_talloc_autofree_ldapmod(mem_ctx, mods);
3335 :
3336 0 : if (mods == NULL) {
3337 0 : DEBUG(4, ("ldapsam_update_group_mapping_entry: mods is empty: "
3338 : "nothing to do\n"));
3339 0 : result = NT_STATUS_OK;
3340 0 : goto done;
3341 : }
3342 :
3343 0 : rc = smbldap_modify(ldap_state->smbldap_state, dn, mods);
3344 :
3345 0 : if (rc != LDAP_SUCCESS) {
3346 0 : result = NT_STATUS_ACCESS_DENIED;
3347 0 : goto done;
3348 : }
3349 :
3350 0 : DEBUG(2, ("ldapsam_update_group_mapping_entry: successfully modified "
3351 : "group %lu in LDAP\n", (unsigned long)map->gid));
3352 :
3353 0 : result = NT_STATUS_OK;
3354 :
3355 0 : done:
3356 0 : TALLOC_FREE(mem_ctx);
3357 0 : return result;
3358 : }
3359 :
3360 : /**********************************************************************
3361 : *********************************************************************/
3362 :
3363 0 : static NTSTATUS ldapsam_delete_group_mapping_entry(struct pdb_methods *methods,
3364 : struct dom_sid sid)
3365 : {
3366 0 : struct ldapsam_privates *priv =
3367 : (struct ldapsam_privates *)methods->private_data;
3368 0 : LDAPMessage *msg, *entry;
3369 0 : int rc;
3370 0 : NTSTATUS result;
3371 0 : TALLOC_CTX *mem_ctx;
3372 0 : char *filter;
3373 0 : struct dom_sid_buf buf;
3374 :
3375 0 : mem_ctx = talloc_new(NULL);
3376 0 : if (mem_ctx == NULL) {
3377 0 : DEBUG(0, ("talloc_new failed\n"));
3378 0 : return NT_STATUS_NO_MEMORY;
3379 : }
3380 :
3381 0 : filter = talloc_asprintf(mem_ctx, "(&(objectClass="LDAP_OBJ_GROUPMAP")("LDAP_ATTRIBUTE_SID"=%s))",
3382 : dom_sid_str_buf(&sid, &buf));
3383 0 : if (filter == NULL) {
3384 0 : result = NT_STATUS_NO_MEMORY;
3385 0 : goto done;
3386 : }
3387 0 : rc = smbldap_search_suffix(priv->smbldap_state, filter,
3388 : get_attr_list(mem_ctx, groupmap_attr_list),
3389 : &msg);
3390 0 : smbldap_talloc_autofree_ldapmsg(mem_ctx, msg);
3391 :
3392 0 : if ((rc != LDAP_SUCCESS) ||
3393 0 : (ldap_count_entries(priv2ld(priv), msg) != 1) ||
3394 0 : ((entry = ldap_first_entry(priv2ld(priv), msg)) == NULL)) {
3395 0 : result = NT_STATUS_NO_SUCH_GROUP;
3396 0 : goto done;
3397 : }
3398 :
3399 0 : rc = ldapsam_delete_entry(priv, mem_ctx, entry, LDAP_OBJ_GROUPMAP,
3400 : get_attr_list(mem_ctx,
3401 : groupmap_attr_list_to_delete));
3402 :
3403 0 : if ((rc == LDAP_NAMING_VIOLATION) ||
3404 0 : (rc == LDAP_NOT_ALLOWED_ON_RDN) ||
3405 : (rc == LDAP_OBJECT_CLASS_VIOLATION)) {
3406 0 : const char *attrs[] = { "sambaGroupType", "description",
3407 : "displayName", "sambaSIDList",
3408 : NULL };
3409 :
3410 : /* Second try. Don't delete the sambaSID attribute, this is
3411 : for "old" entries that are tacked on a winbind
3412 : sambaIdmapEntry. */
3413 :
3414 0 : rc = ldapsam_delete_entry(priv, mem_ctx, entry,
3415 : LDAP_OBJ_GROUPMAP, attrs);
3416 : }
3417 :
3418 0 : if ((rc == LDAP_NAMING_VIOLATION) ||
3419 0 : (rc == LDAP_NOT_ALLOWED_ON_RDN) ||
3420 : (rc == LDAP_OBJECT_CLASS_VIOLATION)) {
3421 0 : const char *attrs[] = { "sambaGroupType", "description",
3422 : "displayName", "sambaSIDList",
3423 : "gidNumber", NULL };
3424 :
3425 : /* Third try. This is a post-3.0.21 alias (containing only
3426 : * sambaSidEntry and sambaGroupMapping classes), we also have
3427 : * to delete the gidNumber attribute, only the sambaSidEntry
3428 : * remains */
3429 :
3430 0 : rc = ldapsam_delete_entry(priv, mem_ctx, entry,
3431 : LDAP_OBJ_GROUPMAP, attrs);
3432 : }
3433 :
3434 0 : result = (rc == LDAP_SUCCESS) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
3435 :
3436 0 : done:
3437 0 : TALLOC_FREE(mem_ctx);
3438 0 : return result;
3439 : }
3440 :
3441 : /**********************************************************************
3442 : *********************************************************************/
3443 :
3444 0 : static NTSTATUS ldapsam_setsamgrent(struct pdb_methods *my_methods,
3445 : bool update)
3446 : {
3447 0 : struct ldapsam_privates *ldap_state =
3448 : (struct ldapsam_privates *)my_methods->private_data;
3449 0 : const char *filter = NULL;
3450 0 : int rc;
3451 0 : const char **attr_list;
3452 :
3453 0 : filter = "(objectclass="LDAP_OBJ_GROUPMAP")";
3454 0 : attr_list = get_attr_list( NULL, groupmap_attr_list );
3455 0 : rc = smbldap_search(ldap_state->smbldap_state, lp_ldap_suffix(),
3456 : LDAP_SCOPE_SUBTREE, filter,
3457 : attr_list, 0, &ldap_state->result);
3458 0 : TALLOC_FREE(attr_list);
3459 :
3460 0 : if (rc != LDAP_SUCCESS) {
3461 0 : DEBUG(0, ("ldapsam_setsamgrent: LDAP search failed: %s\n",
3462 : ldap_err2string(rc)));
3463 0 : DEBUG(3, ("ldapsam_setsamgrent: Query was: %s, %s\n",
3464 : lp_ldap_suffix(), filter));
3465 0 : ldap_msgfree(ldap_state->result);
3466 0 : ldap_state->result = NULL;
3467 0 : return NT_STATUS_UNSUCCESSFUL;
3468 : }
3469 :
3470 0 : DEBUG(2, ("ldapsam_setsamgrent: %d entries in the base!\n",
3471 : ldap_count_entries(
3472 : smbldap_get_ldap(ldap_state->smbldap_state),
3473 : ldap_state->result)));
3474 :
3475 0 : ldap_state->entry =
3476 0 : ldap_first_entry(smbldap_get_ldap(ldap_state->smbldap_state),
3477 : ldap_state->result);
3478 0 : ldap_state->index = 0;
3479 :
3480 0 : return NT_STATUS_OK;
3481 : }
3482 :
3483 : /**********************************************************************
3484 : *********************************************************************/
3485 :
3486 0 : static void ldapsam_endsamgrent(struct pdb_methods *my_methods)
3487 : {
3488 0 : ldapsam_endsampwent(my_methods);
3489 0 : }
3490 :
3491 : /**********************************************************************
3492 : *********************************************************************/
3493 :
3494 0 : static NTSTATUS ldapsam_getsamgrent(struct pdb_methods *my_methods,
3495 : GROUP_MAP *map)
3496 : {
3497 0 : NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
3498 0 : struct ldapsam_privates *ldap_state =
3499 : (struct ldapsam_privates *)my_methods->private_data;
3500 0 : bool bret = False;
3501 :
3502 0 : while (!bret) {
3503 0 : if (!ldap_state->entry)
3504 0 : return ret;
3505 :
3506 0 : ldap_state->index++;
3507 0 : bret = init_group_from_ldap(ldap_state, map,
3508 : ldap_state->entry);
3509 :
3510 0 : ldap_state->entry = ldap_next_entry(
3511 : smbldap_get_ldap(ldap_state->smbldap_state),
3512 : ldap_state->entry);
3513 : }
3514 :
3515 0 : return NT_STATUS_OK;
3516 : }
3517 :
3518 : /**********************************************************************
3519 : *********************************************************************/
3520 :
3521 0 : static NTSTATUS ldapsam_enum_group_mapping(struct pdb_methods *methods,
3522 : const struct dom_sid *domsid, enum lsa_SidType sid_name_use,
3523 : GROUP_MAP ***pp_rmap,
3524 : size_t *p_num_entries,
3525 : bool unix_only)
3526 : {
3527 0 : GROUP_MAP *map = NULL;
3528 0 : size_t entries = 0;
3529 :
3530 0 : *p_num_entries = 0;
3531 0 : *pp_rmap = NULL;
3532 :
3533 0 : if (!NT_STATUS_IS_OK(ldapsam_setsamgrent(methods, False))) {
3534 0 : DEBUG(0, ("ldapsam_enum_group_mapping: Unable to open "
3535 : "passdb\n"));
3536 0 : return NT_STATUS_ACCESS_DENIED;
3537 : }
3538 :
3539 0 : while (true) {
3540 :
3541 0 : map = talloc_zero(NULL, GROUP_MAP);
3542 0 : if (!map) {
3543 0 : return NT_STATUS_NO_MEMORY;
3544 : }
3545 :
3546 0 : if (!NT_STATUS_IS_OK(ldapsam_getsamgrent(methods, map))) {
3547 0 : TALLOC_FREE(map);
3548 0 : break;
3549 : }
3550 :
3551 0 : if (sid_name_use != SID_NAME_UNKNOWN &&
3552 0 : sid_name_use != map->sid_name_use) {
3553 0 : DEBUG(11,("ldapsam_enum_group_mapping: group %s is "
3554 : "not of the requested type\n",
3555 : map->nt_name));
3556 0 : continue;
3557 : }
3558 0 : if (unix_only == ENUM_ONLY_MAPPED && map->gid == -1) {
3559 0 : DEBUG(11,("ldapsam_enum_group_mapping: group %s is "
3560 : "non mapped\n", map->nt_name));
3561 0 : continue;
3562 : }
3563 :
3564 0 : *pp_rmap = talloc_realloc(NULL, *pp_rmap,
3565 : GROUP_MAP *, entries + 1);
3566 0 : if (!(*pp_rmap)) {
3567 0 : DEBUG(0,("ldapsam_enum_group_mapping: Unable to "
3568 : "enlarge group map!\n"));
3569 0 : return NT_STATUS_UNSUCCESSFUL;
3570 : }
3571 :
3572 0 : (*pp_rmap)[entries] = talloc_move((*pp_rmap), &map);
3573 :
3574 0 : entries += 1;
3575 : }
3576 :
3577 0 : ldapsam_endsamgrent(methods);
3578 :
3579 0 : *p_num_entries = entries;
3580 :
3581 0 : return NT_STATUS_OK;
3582 : }
3583 :
3584 0 : static NTSTATUS ldapsam_modify_aliasmem(struct pdb_methods *methods,
3585 : const struct dom_sid *alias,
3586 : const struct dom_sid *member,
3587 : int modop)
3588 : {
3589 0 : struct ldapsam_privates *ldap_state =
3590 : (struct ldapsam_privates *)methods->private_data;
3591 0 : char *dn = NULL;
3592 0 : LDAPMessage *result = NULL;
3593 0 : LDAPMessage *entry = NULL;
3594 0 : int count;
3595 0 : LDAPMod **mods = NULL;
3596 0 : int rc;
3597 0 : enum lsa_SidType type = SID_NAME_USE_NONE;
3598 0 : struct dom_sid_buf tmp;
3599 :
3600 0 : char *filter = NULL;
3601 :
3602 0 : if (sid_check_is_in_builtin(alias)) {
3603 0 : type = SID_NAME_ALIAS;
3604 : }
3605 :
3606 0 : if (sid_check_is_in_our_sam(alias)) {
3607 0 : type = SID_NAME_ALIAS;
3608 : }
3609 :
3610 0 : if (type == SID_NAME_USE_NONE) {
3611 0 : struct dom_sid_buf buf;
3612 0 : DEBUG(5, ("SID %s is neither in builtin nor in our domain!\n",
3613 : dom_sid_str_buf(alias, &buf)));
3614 0 : return NT_STATUS_NO_SUCH_ALIAS;
3615 : }
3616 :
3617 0 : if (asprintf(&filter,
3618 : "(&(objectClass=%s)(sambaSid=%s)(sambaGroupType=%d))",
3619 : LDAP_OBJ_GROUPMAP,
3620 : dom_sid_str_buf(alias, &tmp),
3621 : type) < 0) {
3622 0 : return NT_STATUS_NO_MEMORY;
3623 : }
3624 :
3625 0 : if (ldapsam_search_one_group(ldap_state, filter,
3626 : &result) != LDAP_SUCCESS) {
3627 0 : SAFE_FREE(filter);
3628 0 : return NT_STATUS_NO_SUCH_ALIAS;
3629 : }
3630 :
3631 0 : count = ldap_count_entries(smbldap_get_ldap(ldap_state->smbldap_state),
3632 : result);
3633 :
3634 0 : if (count < 1) {
3635 0 : DEBUG(4, ("ldapsam_modify_aliasmem: Did not find alias\n"));
3636 0 : ldap_msgfree(result);
3637 0 : SAFE_FREE(filter);
3638 0 : return NT_STATUS_NO_SUCH_ALIAS;
3639 : }
3640 :
3641 0 : if (count > 1) {
3642 0 : DEBUG(1, ("ldapsam_modify_aliasmem: Duplicate entries for "
3643 : "filter %s: count=%d\n", filter, count));
3644 0 : ldap_msgfree(result);
3645 0 : SAFE_FREE(filter);
3646 0 : return NT_STATUS_NO_SUCH_ALIAS;
3647 : }
3648 :
3649 0 : SAFE_FREE(filter);
3650 :
3651 0 : entry = ldap_first_entry(smbldap_get_ldap(ldap_state->smbldap_state),
3652 : result);
3653 :
3654 0 : if (!entry) {
3655 0 : ldap_msgfree(result);
3656 0 : return NT_STATUS_UNSUCCESSFUL;
3657 : }
3658 :
3659 0 : dn = smbldap_talloc_dn(talloc_tos(),
3660 : smbldap_get_ldap(ldap_state->smbldap_state),
3661 : entry);
3662 0 : if (!dn) {
3663 0 : ldap_msgfree(result);
3664 0 : return NT_STATUS_UNSUCCESSFUL;
3665 : }
3666 :
3667 0 : smbldap_set_mod(&mods, modop,
3668 : get_attr_key2string(groupmap_attr_list,
3669 : LDAP_ATTR_SID_LIST),
3670 0 : dom_sid_str_buf(member, &tmp));
3671 :
3672 0 : rc = smbldap_modify(ldap_state->smbldap_state, dn, mods);
3673 :
3674 0 : ldap_mods_free(mods, True);
3675 0 : ldap_msgfree(result);
3676 0 : TALLOC_FREE(dn);
3677 :
3678 0 : if (rc == LDAP_TYPE_OR_VALUE_EXISTS) {
3679 0 : return NT_STATUS_MEMBER_IN_ALIAS;
3680 : }
3681 :
3682 0 : if (rc == LDAP_NO_SUCH_ATTRIBUTE) {
3683 0 : return NT_STATUS_MEMBER_NOT_IN_ALIAS;
3684 : }
3685 :
3686 0 : if (rc != LDAP_SUCCESS) {
3687 0 : return NT_STATUS_UNSUCCESSFUL;
3688 : }
3689 :
3690 0 : return NT_STATUS_OK;
3691 : }
3692 :
3693 0 : static NTSTATUS ldapsam_add_aliasmem(struct pdb_methods *methods,
3694 : const struct dom_sid *alias,
3695 : const struct dom_sid *member)
3696 : {
3697 0 : return ldapsam_modify_aliasmem(methods, alias, member, LDAP_MOD_ADD);
3698 : }
3699 :
3700 0 : static NTSTATUS ldapsam_del_aliasmem(struct pdb_methods *methods,
3701 : const struct dom_sid *alias,
3702 : const struct dom_sid *member)
3703 : {
3704 0 : return ldapsam_modify_aliasmem(methods, alias, member,
3705 : LDAP_MOD_DELETE);
3706 : }
3707 :
3708 0 : static NTSTATUS ldapsam_enum_aliasmem(struct pdb_methods *methods,
3709 : const struct dom_sid *alias,
3710 : TALLOC_CTX *mem_ctx,
3711 : struct dom_sid **pp_members,
3712 : size_t *p_num_members)
3713 : {
3714 0 : struct ldapsam_privates *ldap_state =
3715 : (struct ldapsam_privates *)methods->private_data;
3716 0 : LDAPMessage *result = NULL;
3717 0 : LDAPMessage *entry = NULL;
3718 0 : int count;
3719 0 : char **values = NULL;
3720 0 : int i;
3721 0 : char *filter = NULL;
3722 0 : uint32_t num_members = 0;
3723 0 : enum lsa_SidType type = SID_NAME_USE_NONE;
3724 0 : struct dom_sid_buf tmp;
3725 :
3726 0 : *pp_members = NULL;
3727 0 : *p_num_members = 0;
3728 :
3729 0 : if (sid_check_is_in_builtin(alias)) {
3730 0 : type = SID_NAME_ALIAS;
3731 : }
3732 :
3733 0 : if (sid_check_is_in_our_sam(alias)) {
3734 0 : type = SID_NAME_ALIAS;
3735 : }
3736 :
3737 0 : if (type == SID_NAME_USE_NONE) {
3738 0 : DEBUG(5, ("SID %s is neither in builtin nor in our domain!\n",
3739 : dom_sid_str_buf(alias, &tmp)));
3740 0 : return NT_STATUS_NO_SUCH_ALIAS;
3741 : }
3742 :
3743 0 : if (asprintf(&filter,
3744 : "(&(objectClass=%s)(sambaSid=%s)(sambaGroupType=%d))",
3745 : LDAP_OBJ_GROUPMAP,
3746 : dom_sid_str_buf(alias, &tmp),
3747 : type) < 0) {
3748 0 : return NT_STATUS_NO_MEMORY;
3749 : }
3750 :
3751 0 : if (ldapsam_search_one_group(ldap_state, filter,
3752 : &result) != LDAP_SUCCESS) {
3753 0 : SAFE_FREE(filter);
3754 0 : return NT_STATUS_NO_SUCH_ALIAS;
3755 : }
3756 :
3757 0 : count = ldap_count_entries(smbldap_get_ldap(ldap_state->smbldap_state),
3758 : result);
3759 :
3760 0 : if (count < 1) {
3761 0 : DEBUG(4, ("ldapsam_enum_aliasmem: Did not find alias\n"));
3762 0 : ldap_msgfree(result);
3763 0 : SAFE_FREE(filter);
3764 0 : return NT_STATUS_NO_SUCH_ALIAS;
3765 : }
3766 :
3767 0 : if (count > 1) {
3768 0 : DEBUG(1, ("ldapsam_enum_aliasmem: Duplicate entries for "
3769 : "filter %s: count=%d\n", filter, count));
3770 0 : ldap_msgfree(result);
3771 0 : SAFE_FREE(filter);
3772 0 : return NT_STATUS_NO_SUCH_ALIAS;
3773 : }
3774 :
3775 0 : SAFE_FREE(filter);
3776 :
3777 0 : entry = ldap_first_entry(smbldap_get_ldap(ldap_state->smbldap_state),
3778 : result);
3779 :
3780 0 : if (!entry) {
3781 0 : ldap_msgfree(result);
3782 0 : return NT_STATUS_UNSUCCESSFUL;
3783 : }
3784 :
3785 0 : values = ldap_get_values(smbldap_get_ldap(ldap_state->smbldap_state),
3786 : entry,
3787 : get_attr_key2string(groupmap_attr_list,
3788 : LDAP_ATTR_SID_LIST));
3789 :
3790 0 : if (values == NULL) {
3791 0 : ldap_msgfree(result);
3792 0 : return NT_STATUS_OK;
3793 : }
3794 :
3795 0 : count = ldap_count_values(values);
3796 :
3797 0 : for (i=0; i<count; i++) {
3798 0 : struct dom_sid member;
3799 0 : NTSTATUS status;
3800 :
3801 0 : if (!string_to_sid(&member, values[i]))
3802 0 : continue;
3803 :
3804 0 : status = add_sid_to_array(mem_ctx, &member, pp_members,
3805 : &num_members);
3806 0 : if (!NT_STATUS_IS_OK(status)) {
3807 0 : ldap_value_free(values);
3808 0 : ldap_msgfree(result);
3809 0 : return status;
3810 : }
3811 : }
3812 :
3813 0 : *p_num_members = num_members;
3814 0 : ldap_value_free(values);
3815 0 : ldap_msgfree(result);
3816 :
3817 0 : return NT_STATUS_OK;
3818 : }
3819 :
3820 0 : static NTSTATUS ldapsam_alias_memberships(struct pdb_methods *methods,
3821 : TALLOC_CTX *mem_ctx,
3822 : const struct dom_sid *domain_sid,
3823 : const struct dom_sid *members,
3824 : size_t num_members,
3825 : uint32_t **pp_alias_rids,
3826 : size_t *p_num_alias_rids)
3827 : {
3828 0 : struct ldapsam_privates *ldap_state =
3829 : (struct ldapsam_privates *)methods->private_data;
3830 0 : LDAP *ldap_struct;
3831 :
3832 0 : const char *attrs[] = { LDAP_ATTRIBUTE_SID, NULL };
3833 :
3834 0 : LDAPMessage *result = NULL;
3835 0 : LDAPMessage *entry = NULL;
3836 0 : int i;
3837 0 : int rc;
3838 0 : char *filter;
3839 0 : enum lsa_SidType type = SID_NAME_USE_NONE;
3840 0 : bool is_builtin = false;
3841 0 : bool sid_added = false;
3842 :
3843 0 : *pp_alias_rids = NULL;
3844 0 : *p_num_alias_rids = 0;
3845 :
3846 0 : if (sid_check_is_builtin(domain_sid)) {
3847 0 : is_builtin = true;
3848 0 : type = SID_NAME_ALIAS;
3849 : }
3850 :
3851 0 : if (sid_check_is_our_sam(domain_sid)) {
3852 0 : type = SID_NAME_ALIAS;
3853 : }
3854 :
3855 0 : if (type == SID_NAME_USE_NONE) {
3856 0 : struct dom_sid_buf buf;
3857 0 : DEBUG(5, ("SID %s is neither builtin nor domain!\n",
3858 : dom_sid_str_buf(domain_sid, &buf)));
3859 0 : return NT_STATUS_UNSUCCESSFUL;
3860 : }
3861 :
3862 0 : if (num_members == 0) {
3863 0 : return NT_STATUS_OK;
3864 : }
3865 :
3866 0 : filter = talloc_asprintf(mem_ctx,
3867 : "(&(objectclass="LDAP_OBJ_GROUPMAP")(sambaGroupType=%d)(|",
3868 : type);
3869 :
3870 0 : for (i=0; i<num_members; i++) {
3871 0 : struct dom_sid_buf buf;
3872 0 : filter = talloc_asprintf(mem_ctx, "%s(sambaSIDList=%s)",
3873 : filter,
3874 0 : dom_sid_str_buf(&members[i], &buf));
3875 : }
3876 :
3877 0 : filter = talloc_asprintf(mem_ctx, "%s))", filter);
3878 :
3879 0 : if (filter == NULL) {
3880 0 : return NT_STATUS_NO_MEMORY;
3881 : }
3882 :
3883 0 : if (is_builtin &&
3884 0 : ldap_state->search_cache.filter &&
3885 0 : strcmp(ldap_state->search_cache.filter, filter) == 0) {
3886 0 : filter = talloc_move(filter, &ldap_state->search_cache.filter);
3887 0 : result = ldap_state->search_cache.result;
3888 0 : ldap_state->search_cache.result = NULL;
3889 : } else {
3890 0 : rc = smbldap_search(ldap_state->smbldap_state, lp_ldap_suffix(),
3891 : LDAP_SCOPE_SUBTREE, filter, attrs, 0, &result);
3892 0 : if (rc != LDAP_SUCCESS) {
3893 0 : return NT_STATUS_UNSUCCESSFUL;
3894 : }
3895 0 : smbldap_talloc_autofree_ldapmsg(filter, result);
3896 : }
3897 :
3898 0 : ldap_struct = smbldap_get_ldap(ldap_state->smbldap_state);
3899 :
3900 0 : for (entry = ldap_first_entry(ldap_struct, result);
3901 0 : entry != NULL;
3902 0 : entry = ldap_next_entry(ldap_struct, entry))
3903 : {
3904 0 : fstring sid_str;
3905 0 : struct dom_sid sid;
3906 0 : uint32_t rid;
3907 :
3908 0 : if (!smbldap_get_single_attribute(ldap_struct, entry,
3909 : LDAP_ATTRIBUTE_SID,
3910 : sid_str,
3911 : sizeof(sid_str)-1))
3912 0 : continue;
3913 :
3914 0 : if (!string_to_sid(&sid, sid_str))
3915 0 : continue;
3916 :
3917 0 : if (!sid_peek_check_rid(domain_sid, &sid, &rid))
3918 0 : continue;
3919 :
3920 0 : sid_added = true;
3921 :
3922 0 : if (!add_rid_to_array_unique(mem_ctx, rid, pp_alias_rids,
3923 : p_num_alias_rids)) {
3924 0 : return NT_STATUS_NO_MEMORY;
3925 : }
3926 : }
3927 :
3928 0 : if (!is_builtin && !sid_added) {
3929 0 : TALLOC_FREE(ldap_state->search_cache.filter);
3930 : /*
3931 : * Note: result is a talloc child of filter because of the
3932 : * smbldap_talloc_autofree_ldapmsg() usage
3933 : */
3934 0 : ldap_state->search_cache.filter = talloc_move(ldap_state, &filter);
3935 0 : ldap_state->search_cache.result = result;
3936 : }
3937 :
3938 0 : return NT_STATUS_OK;
3939 : }
3940 :
3941 0 : static NTSTATUS ldapsam_set_account_policy_in_ldap(struct pdb_methods *methods,
3942 : enum pdb_policy_type type,
3943 : uint32_t value)
3944 : {
3945 0 : NTSTATUS ntstatus = NT_STATUS_UNSUCCESSFUL;
3946 0 : int rc;
3947 0 : LDAPMod **mods = NULL;
3948 0 : fstring value_string;
3949 0 : const char *policy_attr = NULL;
3950 :
3951 0 : struct ldapsam_privates *ldap_state =
3952 : (struct ldapsam_privates *)methods->private_data;
3953 :
3954 0 : DEBUG(10,("ldapsam_set_account_policy_in_ldap\n"));
3955 :
3956 0 : if (!ldap_state->domain_dn) {
3957 0 : return NT_STATUS_INVALID_PARAMETER;
3958 : }
3959 :
3960 0 : policy_attr = get_account_policy_attr(type);
3961 0 : if (policy_attr == NULL) {
3962 0 : DEBUG(0,("ldapsam_set_account_policy_in_ldap: invalid "
3963 : "policy\n"));
3964 0 : return ntstatus;
3965 : }
3966 :
3967 0 : slprintf(value_string, sizeof(value_string) - 1, "%i", value);
3968 :
3969 0 : smbldap_set_mod(&mods, LDAP_MOD_REPLACE, policy_attr, value_string);
3970 :
3971 0 : rc = smbldap_modify(ldap_state->smbldap_state, ldap_state->domain_dn,
3972 : mods);
3973 :
3974 0 : ldap_mods_free(mods, True);
3975 :
3976 0 : if (rc != LDAP_SUCCESS) {
3977 0 : return ntstatus;
3978 : }
3979 :
3980 0 : if (!cache_account_policy_set(type, value)) {
3981 0 : DEBUG(0,("ldapsam_set_account_policy_in_ldap: failed to "
3982 : "update local tdb cache\n"));
3983 0 : return ntstatus;
3984 : }
3985 :
3986 0 : return NT_STATUS_OK;
3987 : }
3988 :
3989 0 : static NTSTATUS ldapsam_set_account_policy(struct pdb_methods *methods,
3990 : enum pdb_policy_type type,
3991 : uint32_t value)
3992 : {
3993 0 : return ldapsam_set_account_policy_in_ldap(methods, type,
3994 : value);
3995 : }
3996 :
3997 0 : static NTSTATUS ldapsam_get_account_policy_from_ldap(struct pdb_methods *methods,
3998 : enum pdb_policy_type type,
3999 : uint32_t *value)
4000 : {
4001 0 : NTSTATUS ntstatus = NT_STATUS_UNSUCCESSFUL;
4002 0 : LDAPMessage *result = NULL;
4003 0 : LDAPMessage *entry = NULL;
4004 0 : int count;
4005 0 : int rc;
4006 0 : char **vals = NULL;
4007 0 : const char *filter;
4008 0 : const char *policy_attr = NULL;
4009 :
4010 0 : struct ldapsam_privates *ldap_state =
4011 : (struct ldapsam_privates *)methods->private_data;
4012 :
4013 0 : const char *attrs[2];
4014 :
4015 0 : DEBUG(10,("ldapsam_get_account_policy_from_ldap\n"));
4016 :
4017 0 : if (!ldap_state->domain_dn) {
4018 0 : return NT_STATUS_INVALID_PARAMETER;
4019 : }
4020 :
4021 0 : policy_attr = get_account_policy_attr(type);
4022 0 : if (!policy_attr) {
4023 0 : DEBUG(0,("ldapsam_get_account_policy_from_ldap: invalid "
4024 : "policy index: %d\n", type));
4025 0 : return ntstatus;
4026 : }
4027 :
4028 0 : attrs[0] = policy_attr;
4029 0 : attrs[1] = NULL;
4030 :
4031 0 : filter = "(objectClass="LDAP_OBJ_DOMINFO")";
4032 0 : rc = smbldap_search(ldap_state->smbldap_state, ldap_state->domain_dn,
4033 : LDAP_SCOPE_BASE, filter, attrs, 0,
4034 : &result);
4035 0 : if (rc != LDAP_SUCCESS) {
4036 0 : return ntstatus;
4037 : }
4038 :
4039 0 : count = ldap_count_entries(priv2ld(ldap_state), result);
4040 0 : if (count < 1) {
4041 0 : goto out;
4042 : }
4043 :
4044 0 : entry = ldap_first_entry(priv2ld(ldap_state), result);
4045 0 : if (entry == NULL) {
4046 0 : goto out;
4047 : }
4048 :
4049 0 : vals = ldap_get_values(priv2ld(ldap_state), entry, policy_attr);
4050 0 : if (vals == NULL) {
4051 0 : goto out;
4052 : }
4053 :
4054 0 : *value = (uint32_t)atol(vals[0]);
4055 :
4056 0 : ntstatus = NT_STATUS_OK;
4057 :
4058 0 : out:
4059 0 : if (vals)
4060 0 : ldap_value_free(vals);
4061 0 : ldap_msgfree(result);
4062 :
4063 0 : return ntstatus;
4064 : }
4065 :
4066 : /* wrapper around ldapsam_get_account_policy_from_ldap(), handles tdb as cache
4067 :
4068 : - if user hasn't decided to use account policies inside LDAP just reuse the
4069 : old tdb values
4070 :
4071 : - if there is a valid cache entry, return that
4072 : - if there is an LDAP entry, update cache and return
4073 : - otherwise set to default, update cache and return
4074 :
4075 : Guenther
4076 : */
4077 0 : static NTSTATUS ldapsam_get_account_policy(struct pdb_methods *methods,
4078 : enum pdb_policy_type type,
4079 : uint32_t *value)
4080 : {
4081 0 : NTSTATUS ntstatus;
4082 :
4083 0 : if (cache_account_policy_get(type, value)) {
4084 0 : DEBUG(11,("ldapsam_get_account_policy: got valid value from "
4085 : "cache\n"));
4086 0 : return NT_STATUS_OK;
4087 : }
4088 :
4089 0 : ntstatus = ldapsam_get_account_policy_from_ldap(methods, type,
4090 : value);
4091 0 : if (NT_STATUS_IS_OK(ntstatus)) {
4092 0 : goto update_cache;
4093 : }
4094 :
4095 0 : DEBUG(10,("ldapsam_get_account_policy: failed to retrieve from "
4096 : "ldap\n"));
4097 :
4098 : #if 0
4099 : /* should we automagically migrate old tdb value here ? */
4100 : if (account_policy_get(type, value))
4101 : goto update_ldap;
4102 :
4103 : DEBUG(10,("ldapsam_get_account_policy: no tdb for %d, trying "
4104 : "default\n", type));
4105 : #endif
4106 :
4107 0 : if (!account_policy_get_default(type, value)) {
4108 0 : return ntstatus;
4109 : }
4110 :
4111 : /* update_ldap: */
4112 :
4113 0 : ntstatus = ldapsam_set_account_policy(methods, type, *value);
4114 0 : if (!NT_STATUS_IS_OK(ntstatus)) {
4115 0 : return ntstatus;
4116 : }
4117 :
4118 0 : update_cache:
4119 :
4120 0 : if (!cache_account_policy_set(type, *value)) {
4121 0 : DEBUG(0,("ldapsam_get_account_policy: failed to update local "
4122 : "tdb as a cache\n"));
4123 0 : return NT_STATUS_UNSUCCESSFUL;
4124 : }
4125 :
4126 0 : return NT_STATUS_OK;
4127 : }
4128 :
4129 0 : static NTSTATUS ldapsam_lookup_rids(struct pdb_methods *methods,
4130 : const struct dom_sid *domain_sid,
4131 : int num_rids,
4132 : uint32_t *rids,
4133 : const char **names,
4134 : enum lsa_SidType *attrs)
4135 : {
4136 0 : struct ldapsam_privates *ldap_state =
4137 : (struct ldapsam_privates *)methods->private_data;
4138 0 : LDAPMessage *msg = NULL;
4139 0 : LDAPMessage *entry;
4140 0 : char *allsids = NULL;
4141 0 : size_t i, num_mapped;
4142 0 : int rc;
4143 0 : NTSTATUS result = NT_STATUS_NO_MEMORY;
4144 0 : TALLOC_CTX *mem_ctx;
4145 0 : LDAP *ld;
4146 0 : bool is_builtin;
4147 :
4148 0 : mem_ctx = talloc_new(NULL);
4149 0 : if (mem_ctx == NULL) {
4150 0 : DEBUG(0, ("talloc_new failed\n"));
4151 0 : goto done;
4152 : }
4153 :
4154 0 : if (!sid_check_is_builtin(domain_sid) &&
4155 0 : !sid_check_is_our_sam(domain_sid)) {
4156 0 : result = NT_STATUS_INVALID_PARAMETER;
4157 0 : goto done;
4158 : }
4159 :
4160 0 : if (num_rids == 0) {
4161 0 : result = NT_STATUS_NONE_MAPPED;
4162 0 : goto done;
4163 : }
4164 :
4165 0 : for (i=0; i<num_rids; i++)
4166 0 : attrs[i] = SID_NAME_UNKNOWN;
4167 :
4168 0 : allsids = talloc_strdup(mem_ctx, "");
4169 0 : if (allsids == NULL) {
4170 0 : goto done;
4171 : }
4172 :
4173 0 : for (i=0; i<num_rids; i++) {
4174 0 : struct dom_sid sid;
4175 0 : struct dom_sid_buf buf;
4176 0 : sid_compose(&sid, domain_sid, rids[i]);
4177 0 : allsids = talloc_asprintf_append_buffer(
4178 : allsids,
4179 : "(sambaSid=%s)",
4180 : dom_sid_str_buf(&sid, &buf));
4181 0 : if (allsids == NULL) {
4182 0 : goto done;
4183 : }
4184 : }
4185 :
4186 : /* First look for users */
4187 :
4188 : {
4189 0 : char *filter;
4190 0 : const char *ldap_attrs[] = { "uid", "sambaSid", NULL };
4191 :
4192 0 : filter = talloc_asprintf(
4193 : mem_ctx, ("(&(objectClass="LDAP_OBJ_SAMBASAMACCOUNT")(|%s))"),
4194 : allsids);
4195 :
4196 0 : if (filter == NULL) {
4197 0 : goto done;
4198 : }
4199 :
4200 0 : rc = smbldap_search(ldap_state->smbldap_state,
4201 : lp_ldap_user_suffix(talloc_tos()),
4202 : LDAP_SCOPE_SUBTREE, filter, ldap_attrs, 0,
4203 : &msg);
4204 0 : smbldap_talloc_autofree_ldapmsg(mem_ctx, msg);
4205 : }
4206 :
4207 0 : if (rc != LDAP_SUCCESS)
4208 0 : goto done;
4209 :
4210 0 : ld = smbldap_get_ldap(ldap_state->smbldap_state);
4211 0 : num_mapped = 0;
4212 :
4213 0 : for (entry = ldap_first_entry(ld, msg);
4214 0 : entry != NULL;
4215 0 : entry = ldap_next_entry(ld, entry)) {
4216 0 : uint32_t rid;
4217 0 : int rid_index;
4218 0 : const char *name;
4219 :
4220 0 : if (!ldapsam_extract_rid_from_entry(ld, entry, domain_sid,
4221 : &rid)) {
4222 0 : DEBUG(2, ("Could not find sid from ldap entry\n"));
4223 0 : continue;
4224 : }
4225 :
4226 0 : name = smbldap_talloc_single_attribute(ld, entry, "uid",
4227 : names);
4228 0 : if (name == NULL) {
4229 0 : DEBUG(2, ("Could not retrieve uid attribute\n"));
4230 0 : continue;
4231 : }
4232 :
4233 0 : for (rid_index = 0; rid_index < num_rids; rid_index++) {
4234 0 : if (rid == rids[rid_index])
4235 0 : break;
4236 : }
4237 :
4238 0 : if (rid_index == num_rids) {
4239 0 : DEBUG(2, ("Got a RID not asked for: %d\n", rid));
4240 0 : continue;
4241 : }
4242 :
4243 0 : attrs[rid_index] = SID_NAME_USER;
4244 0 : names[rid_index] = name;
4245 0 : num_mapped += 1;
4246 : }
4247 :
4248 0 : if (num_mapped == num_rids) {
4249 : /* No need to look for groups anymore -- we're done */
4250 0 : result = NT_STATUS_OK;
4251 0 : goto done;
4252 : }
4253 :
4254 : /* Same game for groups */
4255 :
4256 : {
4257 0 : char *filter;
4258 0 : const char *ldap_attrs[] = { "cn", "displayName", "sambaSid",
4259 : "sambaGroupType", NULL };
4260 :
4261 0 : filter = talloc_asprintf(
4262 : mem_ctx, "(&(objectClass="LDAP_OBJ_GROUPMAP")(|%s))",
4263 : allsids);
4264 0 : if (filter == NULL) {
4265 0 : goto done;
4266 : }
4267 :
4268 0 : rc = smbldap_search(ldap_state->smbldap_state,
4269 : lp_ldap_suffix(),
4270 : LDAP_SCOPE_SUBTREE, filter, ldap_attrs, 0,
4271 : &msg);
4272 0 : smbldap_talloc_autofree_ldapmsg(mem_ctx, msg);
4273 : }
4274 :
4275 0 : if (rc != LDAP_SUCCESS)
4276 0 : goto done;
4277 :
4278 : /* ldap_struct might have changed due to a reconnect */
4279 :
4280 0 : ld = smbldap_get_ldap(ldap_state->smbldap_state);
4281 :
4282 : /* For consistency checks, we already checked we're only domain or builtin */
4283 :
4284 0 : is_builtin = sid_check_is_builtin(domain_sid);
4285 :
4286 0 : for (entry = ldap_first_entry(ld, msg);
4287 0 : entry != NULL;
4288 0 : entry = ldap_next_entry(ld, entry))
4289 : {
4290 0 : uint32_t rid;
4291 0 : int rid_index;
4292 0 : const char *attr;
4293 0 : enum lsa_SidType type;
4294 0 : const char *dn = smbldap_talloc_dn(mem_ctx, ld, entry);
4295 :
4296 0 : attr = smbldap_talloc_single_attribute(ld, entry, "sambaGroupType",
4297 : mem_ctx);
4298 0 : if (attr == NULL) {
4299 0 : DEBUG(2, ("Could not extract type from ldap entry %s\n",
4300 : dn));
4301 0 : continue;
4302 : }
4303 :
4304 0 : type = (enum lsa_SidType)atol(attr);
4305 :
4306 : /* Consistency checks */
4307 0 : if ((is_builtin && (type != SID_NAME_ALIAS)) ||
4308 0 : (!is_builtin && ((type != SID_NAME_ALIAS) &&
4309 0 : (type != SID_NAME_DOM_GRP)))) {
4310 0 : DEBUG(2, ("Rejecting invalid group mapping entry %s\n", dn));
4311 : }
4312 :
4313 0 : if (!ldapsam_extract_rid_from_entry(ld, entry, domain_sid,
4314 : &rid)) {
4315 0 : DEBUG(2, ("Could not find sid from ldap entry %s\n", dn));
4316 0 : continue;
4317 : }
4318 :
4319 0 : attr = smbldap_talloc_single_attribute(ld, entry, "displayName", names);
4320 :
4321 0 : if (attr == NULL) {
4322 0 : DEBUG(10, ("Could not retrieve 'displayName' attribute from %s\n",
4323 : dn));
4324 0 : attr = smbldap_talloc_single_attribute(ld, entry, "cn", names);
4325 : }
4326 :
4327 0 : if (attr == NULL) {
4328 0 : DEBUG(2, ("Could not retrieve naming attribute from %s\n",
4329 : dn));
4330 0 : continue;
4331 : }
4332 :
4333 0 : for (rid_index = 0; rid_index < num_rids; rid_index++) {
4334 0 : if (rid == rids[rid_index])
4335 0 : break;
4336 : }
4337 :
4338 0 : if (rid_index == num_rids) {
4339 0 : DEBUG(2, ("Got a RID not asked for: %d\n", rid));
4340 0 : continue;
4341 : }
4342 :
4343 0 : attrs[rid_index] = type;
4344 0 : names[rid_index] = attr;
4345 0 : num_mapped += 1;
4346 : }
4347 :
4348 0 : result = NT_STATUS_NONE_MAPPED;
4349 :
4350 0 : if (num_mapped > 0)
4351 0 : result = (num_mapped == num_rids) ?
4352 0 : NT_STATUS_OK : STATUS_SOME_UNMAPPED;
4353 0 : done:
4354 0 : TALLOC_FREE(mem_ctx);
4355 0 : return result;
4356 : }
4357 :
4358 0 : static char *get_ldap_filter(TALLOC_CTX *mem_ctx, const char *username)
4359 : {
4360 0 : char *filter = NULL;
4361 0 : char *escaped = NULL;
4362 0 : char *result = NULL;
4363 :
4364 0 : if (asprintf(&filter, "(&%s(objectclass=%s))",
4365 : "(uid=%u)", LDAP_OBJ_SAMBASAMACCOUNT) < 0) {
4366 0 : goto done;
4367 : }
4368 :
4369 0 : escaped = escape_ldap_string(talloc_tos(), username);
4370 0 : if (escaped == NULL) goto done;
4371 :
4372 0 : result = talloc_string_sub(mem_ctx, filter, "%u", username);
4373 :
4374 0 : done:
4375 0 : SAFE_FREE(filter);
4376 0 : TALLOC_FREE(escaped);
4377 :
4378 0 : return result;
4379 : }
4380 :
4381 0 : static const char **talloc_attrs(TALLOC_CTX *mem_ctx, ...)
4382 : {
4383 0 : int i, num = 0;
4384 0 : va_list ap;
4385 0 : const char **result;
4386 :
4387 0 : va_start(ap, mem_ctx);
4388 0 : while (va_arg(ap, const char *) != NULL)
4389 0 : num += 1;
4390 0 : va_end(ap);
4391 :
4392 0 : if ((result = talloc_array(mem_ctx, const char *, num+1)) == NULL) {
4393 0 : return NULL;
4394 : }
4395 :
4396 0 : va_start(ap, mem_ctx);
4397 0 : for (i=0; i<num; i++) {
4398 0 : result[i] = talloc_strdup(result, va_arg(ap, const char*));
4399 0 : if (result[i] == NULL) {
4400 0 : talloc_free(result);
4401 0 : va_end(ap);
4402 0 : return NULL;
4403 : }
4404 : }
4405 0 : va_end(ap);
4406 :
4407 0 : result[num] = NULL;
4408 0 : return result;
4409 : }
4410 :
4411 : struct ldap_search_state {
4412 : struct smbldap_state *connection;
4413 :
4414 : uint32_t acct_flags;
4415 : uint16_t group_type;
4416 :
4417 : const char *base;
4418 : int scope;
4419 : const char *filter;
4420 : const char **attrs;
4421 : int attrsonly;
4422 : void *pagedresults_cookie;
4423 :
4424 : LDAPMessage *entries, *current_entry;
4425 : bool (*ldap2displayentry)(struct ldap_search_state *state,
4426 : TALLOC_CTX *mem_ctx,
4427 : LDAP *ld, LDAPMessage *entry,
4428 : struct samr_displayentry *result);
4429 : };
4430 :
4431 0 : static bool ldapsam_search_firstpage(struct pdb_search *search)
4432 : {
4433 0 : struct ldap_search_state *state =
4434 : (struct ldap_search_state *)search->private_data;
4435 0 : LDAP *ld;
4436 0 : int rc = LDAP_OPERATIONS_ERROR;
4437 :
4438 0 : state->entries = NULL;
4439 :
4440 0 : if (smbldap_get_paged_results(state->connection)) {
4441 0 : rc = smbldap_search_paged(state->connection, state->base,
4442 : state->scope, state->filter,
4443 : state->attrs, state->attrsonly,
4444 : lp_ldap_page_size(), &state->entries,
4445 : &state->pagedresults_cookie);
4446 : }
4447 :
4448 0 : if ((rc != LDAP_SUCCESS) || (state->entries == NULL)) {
4449 :
4450 0 : if (state->entries != NULL) {
4451 : /* Left over from unsuccessful paged attempt */
4452 0 : ldap_msgfree(state->entries);
4453 0 : state->entries = NULL;
4454 : }
4455 :
4456 0 : rc = smbldap_search(state->connection, state->base,
4457 : state->scope, state->filter, state->attrs,
4458 : state->attrsonly, &state->entries);
4459 :
4460 0 : if ((rc != LDAP_SUCCESS) || (state->entries == NULL))
4461 0 : return False;
4462 :
4463 : /* Ok, the server was lying. It told us it could do paged
4464 : * searches when it could not. */
4465 0 : smbldap_set_paged_results(state->connection, false);
4466 : }
4467 :
4468 0 : ld = smbldap_get_ldap(state->connection);
4469 0 : if ( ld == NULL) {
4470 0 : DEBUG(5, ("Don't have an LDAP connection right after a "
4471 : "search\n"));
4472 0 : return False;
4473 : }
4474 0 : state->current_entry = ldap_first_entry(ld, state->entries);
4475 :
4476 0 : return True;
4477 : }
4478 :
4479 0 : static bool ldapsam_search_nextpage(struct pdb_search *search)
4480 : {
4481 0 : struct ldap_search_state *state =
4482 : (struct ldap_search_state *)search->private_data;
4483 0 : int rc;
4484 :
4485 0 : if (!smbldap_get_paged_results(state->connection)) {
4486 : /* There is no next page when there are no paged results */
4487 0 : return False;
4488 : }
4489 :
4490 0 : rc = smbldap_search_paged(state->connection, state->base,
4491 : state->scope, state->filter, state->attrs,
4492 : state->attrsonly, lp_ldap_page_size(),
4493 : &state->entries,
4494 : &state->pagedresults_cookie);
4495 :
4496 0 : if ((rc != LDAP_SUCCESS) || (state->entries == NULL))
4497 0 : return False;
4498 :
4499 0 : state->current_entry = ldap_first_entry(
4500 : smbldap_get_ldap(state->connection), state->entries);
4501 :
4502 0 : if (state->current_entry == NULL) {
4503 0 : ldap_msgfree(state->entries);
4504 0 : state->entries = NULL;
4505 0 : return false;
4506 : }
4507 :
4508 0 : return True;
4509 : }
4510 :
4511 0 : static bool ldapsam_search_next_entry(struct pdb_search *search,
4512 : struct samr_displayentry *entry)
4513 : {
4514 0 : struct ldap_search_state *state =
4515 : (struct ldap_search_state *)search->private_data;
4516 0 : bool result;
4517 :
4518 0 : retry:
4519 0 : if ((state->entries == NULL) && (state->pagedresults_cookie == NULL))
4520 0 : return False;
4521 :
4522 0 : if ((state->entries == NULL) &&
4523 0 : !ldapsam_search_nextpage(search))
4524 0 : return False;
4525 :
4526 0 : if (state->current_entry == NULL) {
4527 0 : return false;
4528 : }
4529 :
4530 0 : result = state->ldap2displayentry(state, search,
4531 : smbldap_get_ldap(state->connection),
4532 : state->current_entry, entry);
4533 :
4534 0 : if (!result) {
4535 0 : char *dn;
4536 0 : dn = ldap_get_dn(smbldap_get_ldap(state->connection),
4537 : state->current_entry);
4538 0 : DEBUG(5, ("Skipping entry %s\n", dn != NULL ? dn : "<NULL>"));
4539 0 : if (dn != NULL) ldap_memfree(dn);
4540 : }
4541 :
4542 0 : state->current_entry = ldap_next_entry(
4543 : smbldap_get_ldap(state->connection), state->current_entry);
4544 :
4545 0 : if (state->current_entry == NULL) {
4546 0 : ldap_msgfree(state->entries);
4547 0 : state->entries = NULL;
4548 : }
4549 :
4550 0 : if (!result) goto retry;
4551 :
4552 0 : return True;
4553 : }
4554 :
4555 0 : static void ldapsam_search_end(struct pdb_search *search)
4556 : {
4557 0 : struct ldap_search_state *state =
4558 : (struct ldap_search_state *)search->private_data;
4559 0 : int rc;
4560 :
4561 0 : if (state->pagedresults_cookie == NULL)
4562 0 : return;
4563 :
4564 0 : if (state->entries != NULL)
4565 0 : ldap_msgfree(state->entries);
4566 :
4567 0 : state->entries = NULL;
4568 0 : state->current_entry = NULL;
4569 :
4570 0 : if (!smbldap_get_paged_results(state->connection)) {
4571 0 : return;
4572 : }
4573 :
4574 : /* Tell the LDAP server we're not interested in the rest anymore. */
4575 :
4576 0 : rc = smbldap_search_paged(state->connection, state->base, state->scope,
4577 : state->filter, state->attrs,
4578 : state->attrsonly, 0, &state->entries,
4579 : &state->pagedresults_cookie);
4580 :
4581 0 : if (rc != LDAP_SUCCESS)
4582 0 : DEBUG(5, ("Could not end search properly\n"));
4583 :
4584 0 : return;
4585 : }
4586 :
4587 0 : static bool ldapuser2displayentry(struct ldap_search_state *state,
4588 : TALLOC_CTX *mem_ctx,
4589 : LDAP *ld, LDAPMessage *entry,
4590 : struct samr_displayentry *result)
4591 : {
4592 0 : char **vals;
4593 0 : size_t converted_size;
4594 0 : struct dom_sid sid;
4595 0 : uint32_t acct_flags;
4596 :
4597 0 : vals = ldap_get_values(ld, entry, "sambaAcctFlags");
4598 0 : if ((vals == NULL) || (vals[0] == NULL)) {
4599 0 : acct_flags = ACB_NORMAL;
4600 : } else {
4601 0 : acct_flags = pdb_decode_acct_ctrl(vals[0]);
4602 0 : ldap_value_free(vals);
4603 : }
4604 :
4605 0 : if ((state->acct_flags != 0) &&
4606 0 : ((state->acct_flags & acct_flags) == 0))
4607 0 : return False;
4608 :
4609 0 : result->acct_flags = acct_flags;
4610 0 : result->account_name = "";
4611 0 : result->fullname = "";
4612 0 : result->description = "";
4613 :
4614 0 : vals = ldap_get_values(ld, entry, "uid");
4615 0 : if ((vals == NULL) || (vals[0] == NULL)) {
4616 0 : DEBUG(5, ("\"uid\" not found\n"));
4617 0 : return False;
4618 : }
4619 0 : if (!pull_utf8_talloc(mem_ctx,
4620 0 : discard_const_p(char *, &result->account_name),
4621 : vals[0], &converted_size))
4622 : {
4623 0 : DEBUG(0,("ldapuser2displayentry: pull_utf8_talloc failed: %s\n",
4624 : strerror(errno)));
4625 : }
4626 :
4627 0 : ldap_value_free(vals);
4628 :
4629 0 : vals = ldap_get_values(ld, entry, "displayName");
4630 0 : if ((vals == NULL) || (vals[0] == NULL))
4631 0 : DEBUG(8, ("\"displayName\" not found\n"));
4632 0 : else if (!pull_utf8_talloc(mem_ctx,
4633 0 : discard_const_p(char *, &result->fullname),
4634 : vals[0], &converted_size))
4635 : {
4636 0 : DEBUG(0,("ldapuser2displayentry: pull_utf8_talloc failed: %s\n",
4637 : strerror(errno)));
4638 : }
4639 :
4640 0 : ldap_value_free(vals);
4641 :
4642 0 : vals = ldap_get_values(ld, entry, "description");
4643 0 : if ((vals == NULL) || (vals[0] == NULL))
4644 0 : DEBUG(8, ("\"description\" not found\n"));
4645 0 : else if (!pull_utf8_talloc(mem_ctx,
4646 0 : discard_const_p(char *, &result->description),
4647 : vals[0], &converted_size))
4648 : {
4649 0 : DEBUG(0,("ldapuser2displayentry: pull_utf8_talloc failed: %s\n",
4650 : strerror(errno)));
4651 : }
4652 :
4653 0 : ldap_value_free(vals);
4654 :
4655 0 : if ((result->account_name == NULL) ||
4656 0 : (result->fullname == NULL) ||
4657 0 : (result->description == NULL)) {
4658 0 : DEBUG(0, ("talloc failed\n"));
4659 0 : return False;
4660 : }
4661 :
4662 0 : vals = ldap_get_values(ld, entry, "sambaSid");
4663 0 : if ((vals == NULL) || (vals[0] == NULL)) {
4664 0 : DEBUG(0, ("\"objectSid\" not found\n"));
4665 0 : return False;
4666 : }
4667 :
4668 0 : if (!string_to_sid(&sid, vals[0])) {
4669 0 : DEBUG(0, ("Could not convert %s to SID\n", vals[0]));
4670 0 : ldap_value_free(vals);
4671 0 : return False;
4672 : }
4673 0 : ldap_value_free(vals);
4674 :
4675 0 : if (!sid_peek_check_rid(get_global_sam_sid(), &sid, &result->rid)) {
4676 0 : struct dom_sid_buf buf;
4677 0 : DEBUG(0, ("sid %s does not belong to our domain\n",
4678 : dom_sid_str_buf(&sid, &buf)));
4679 0 : return False;
4680 : }
4681 :
4682 0 : return True;
4683 : }
4684 :
4685 :
4686 0 : static bool ldapsam_search_users(struct pdb_methods *methods,
4687 : struct pdb_search *search,
4688 : uint32_t acct_flags)
4689 : {
4690 0 : struct ldapsam_privates *ldap_state =
4691 : (struct ldapsam_privates *)methods->private_data;
4692 0 : struct ldap_search_state *state;
4693 :
4694 0 : state = talloc(search, struct ldap_search_state);
4695 0 : if (state == NULL) {
4696 0 : DEBUG(0, ("talloc failed\n"));
4697 0 : return False;
4698 : }
4699 :
4700 0 : state->connection = ldap_state->smbldap_state;
4701 :
4702 0 : if ((acct_flags != 0) && ((acct_flags & ACB_NORMAL) != 0))
4703 0 : state->base = lp_ldap_user_suffix(talloc_tos());
4704 0 : else if ((acct_flags != 0) &&
4705 0 : ((acct_flags & (ACB_WSTRUST|ACB_SVRTRUST|ACB_DOMTRUST)) != 0))
4706 0 : state->base = lp_ldap_machine_suffix(talloc_tos());
4707 : else
4708 0 : state->base = lp_ldap_suffix();
4709 :
4710 0 : state->acct_flags = acct_flags;
4711 0 : state->base = talloc_strdup(search, state->base);
4712 0 : state->scope = LDAP_SCOPE_SUBTREE;
4713 0 : state->filter = get_ldap_filter(search, "*");
4714 0 : state->attrs = talloc_attrs(search, "uid", "sambaSid",
4715 : "displayName", "description",
4716 : "sambaAcctFlags", NULL);
4717 0 : state->attrsonly = 0;
4718 0 : state->pagedresults_cookie = NULL;
4719 0 : state->entries = NULL;
4720 0 : state->ldap2displayentry = ldapuser2displayentry;
4721 :
4722 0 : if ((state->filter == NULL) || (state->attrs == NULL)) {
4723 0 : DEBUG(0, ("talloc failed\n"));
4724 0 : return False;
4725 : }
4726 :
4727 0 : search->private_data = state;
4728 0 : search->next_entry = ldapsam_search_next_entry;
4729 0 : search->search_end = ldapsam_search_end;
4730 :
4731 0 : return ldapsam_search_firstpage(search);
4732 : }
4733 :
4734 0 : static bool ldapgroup2displayentry(struct ldap_search_state *state,
4735 : TALLOC_CTX *mem_ctx,
4736 : LDAP *ld, LDAPMessage *entry,
4737 : struct samr_displayentry *result)
4738 : {
4739 0 : char **vals;
4740 0 : size_t converted_size;
4741 0 : struct dom_sid sid;
4742 0 : uint16_t group_type;
4743 :
4744 0 : result->account_name = "";
4745 0 : result->fullname = "";
4746 0 : result->description = "";
4747 :
4748 :
4749 0 : vals = ldap_get_values(ld, entry, "sambaGroupType");
4750 0 : if ((vals == NULL) || (vals[0] == NULL)) {
4751 0 : DEBUG(5, ("\"sambaGroupType\" not found\n"));
4752 0 : if (vals != NULL) {
4753 0 : ldap_value_free(vals);
4754 : }
4755 0 : return False;
4756 : }
4757 :
4758 0 : group_type = atoi(vals[0]);
4759 :
4760 0 : if ((state->group_type != 0) &&
4761 0 : ((state->group_type != group_type))) {
4762 0 : ldap_value_free(vals);
4763 0 : return False;
4764 : }
4765 :
4766 0 : ldap_value_free(vals);
4767 :
4768 : /* display name is the NT group name */
4769 :
4770 0 : vals = ldap_get_values(ld, entry, "displayName");
4771 0 : if ((vals == NULL) || (vals[0] == NULL)) {
4772 0 : DEBUG(8, ("\"displayName\" not found\n"));
4773 :
4774 : /* fallback to the 'cn' attribute */
4775 0 : vals = ldap_get_values(ld, entry, "cn");
4776 0 : if ((vals == NULL) || (vals[0] == NULL)) {
4777 0 : DEBUG(5, ("\"cn\" not found\n"));
4778 0 : return False;
4779 : }
4780 0 : if (!pull_utf8_talloc(mem_ctx,
4781 0 : discard_const_p(char *,
4782 : &result->account_name),
4783 : vals[0], &converted_size))
4784 : {
4785 0 : DEBUG(0,("ldapgroup2displayentry: pull_utf8_talloc "
4786 : "failed: %s\n", strerror(errno)));
4787 : }
4788 : }
4789 0 : else if (!pull_utf8_talloc(mem_ctx,
4790 0 : discard_const_p(char *,
4791 : &result->account_name),
4792 : vals[0], &converted_size))
4793 : {
4794 0 : DEBUG(0,("ldapgroup2displayentry: pull_utf8_talloc failed: %s\n",
4795 : strerror(errno)));
4796 : }
4797 :
4798 0 : ldap_value_free(vals);
4799 :
4800 0 : vals = ldap_get_values(ld, entry, "description");
4801 0 : if ((vals == NULL) || (vals[0] == NULL))
4802 0 : DEBUG(8, ("\"description\" not found\n"));
4803 0 : else if (!pull_utf8_talloc(mem_ctx,
4804 0 : discard_const_p(char *, &result->description),
4805 : vals[0], &converted_size))
4806 : {
4807 0 : DEBUG(0,("ldapgroup2displayentry: pull_utf8_talloc failed: %s\n",
4808 : strerror(errno)));
4809 : }
4810 0 : ldap_value_free(vals);
4811 :
4812 0 : if ((result->account_name == NULL) ||
4813 0 : (result->fullname == NULL) ||
4814 0 : (result->description == NULL)) {
4815 0 : DEBUG(0, ("talloc failed\n"));
4816 0 : return False;
4817 : }
4818 :
4819 0 : vals = ldap_get_values(ld, entry, "sambaSid");
4820 0 : if ((vals == NULL) || (vals[0] == NULL)) {
4821 0 : DEBUG(0, ("\"objectSid\" not found\n"));
4822 0 : if (vals != NULL) {
4823 0 : ldap_value_free(vals);
4824 : }
4825 0 : return False;
4826 : }
4827 :
4828 0 : if (!string_to_sid(&sid, vals[0])) {
4829 0 : DEBUG(0, ("Could not convert %s to SID\n", vals[0]));
4830 0 : return False;
4831 : }
4832 :
4833 0 : ldap_value_free(vals);
4834 :
4835 0 : switch (group_type) {
4836 0 : case SID_NAME_DOM_GRP:
4837 : case SID_NAME_ALIAS:
4838 :
4839 0 : if (!sid_peek_check_rid(get_global_sam_sid(), &sid, &result->rid)
4840 0 : && !sid_peek_check_rid(&global_sid_Builtin, &sid, &result->rid))
4841 : {
4842 0 : struct dom_sid_buf buf;
4843 0 : DEBUG(0, ("%s is not in our domain\n",
4844 : dom_sid_str_buf(&sid, &buf)));
4845 0 : return False;
4846 : }
4847 0 : break;
4848 :
4849 0 : default:
4850 0 : DEBUG(0,("unknown group type: %d\n", group_type));
4851 0 : return False;
4852 : }
4853 :
4854 0 : result->acct_flags = 0;
4855 :
4856 0 : return True;
4857 : }
4858 :
4859 0 : static bool ldapsam_search_grouptype(struct pdb_methods *methods,
4860 : struct pdb_search *search,
4861 : const struct dom_sid *sid,
4862 : enum lsa_SidType type)
4863 : {
4864 0 : struct ldapsam_privates *ldap_state =
4865 : (struct ldapsam_privates *)methods->private_data;
4866 0 : struct ldap_search_state *state;
4867 0 : struct dom_sid_buf tmp;
4868 :
4869 0 : state = talloc(search, struct ldap_search_state);
4870 0 : if (state == NULL) {
4871 0 : DEBUG(0, ("talloc failed\n"));
4872 0 : return False;
4873 : }
4874 :
4875 0 : state->connection = ldap_state->smbldap_state;
4876 :
4877 0 : state->base = lp_ldap_suffix();
4878 0 : state->connection = ldap_state->smbldap_state;
4879 0 : state->scope = LDAP_SCOPE_SUBTREE;
4880 0 : state->filter = talloc_asprintf(search, "(&(objectclass="LDAP_OBJ_GROUPMAP")"
4881 : "(sambaGroupType=%d)(sambaSID=%s*))",
4882 : type,
4883 : dom_sid_str_buf(sid, &tmp));
4884 0 : state->attrs = talloc_attrs(search, "cn", "sambaSid",
4885 : "displayName", "description",
4886 : "sambaGroupType", NULL);
4887 0 : state->attrsonly = 0;
4888 0 : state->pagedresults_cookie = NULL;
4889 0 : state->entries = NULL;
4890 0 : state->group_type = type;
4891 0 : state->ldap2displayentry = ldapgroup2displayentry;
4892 :
4893 0 : if ((state->filter == NULL) || (state->attrs == NULL)) {
4894 0 : DEBUG(0, ("talloc failed\n"));
4895 0 : return False;
4896 : }
4897 :
4898 0 : search->private_data = state;
4899 0 : search->next_entry = ldapsam_search_next_entry;
4900 0 : search->search_end = ldapsam_search_end;
4901 :
4902 0 : return ldapsam_search_firstpage(search);
4903 : }
4904 :
4905 0 : static bool ldapsam_search_groups(struct pdb_methods *methods,
4906 : struct pdb_search *search)
4907 : {
4908 0 : return ldapsam_search_grouptype(methods, search, get_global_sam_sid(), SID_NAME_DOM_GRP);
4909 : }
4910 :
4911 0 : static bool ldapsam_search_aliases(struct pdb_methods *methods,
4912 : struct pdb_search *search,
4913 : const struct dom_sid *sid)
4914 : {
4915 0 : return ldapsam_search_grouptype(methods, search, sid, SID_NAME_ALIAS);
4916 : }
4917 :
4918 0 : static uint32_t ldapsam_capabilities(struct pdb_methods *methods)
4919 : {
4920 0 : return PDB_CAP_STORE_RIDS;
4921 : }
4922 :
4923 0 : static NTSTATUS ldapsam_get_new_rid(struct ldapsam_privates *priv,
4924 : uint32_t *rid)
4925 : {
4926 0 : struct smbldap_state *smbldap_state = priv->smbldap_state;
4927 :
4928 0 : LDAPMessage *result = NULL;
4929 0 : LDAPMessage *entry = NULL;
4930 0 : LDAPMod **mods = NULL;
4931 0 : NTSTATUS status;
4932 0 : char *value;
4933 0 : int rc;
4934 0 : uint32_t nextRid = 0;
4935 0 : const char *dn;
4936 0 : uint32_t tmp;
4937 0 : int error = 0;
4938 :
4939 0 : TALLOC_CTX *mem_ctx;
4940 :
4941 0 : mem_ctx = talloc_new(NULL);
4942 0 : if (mem_ctx == NULL) {
4943 0 : DEBUG(0, ("talloc_new failed\n"));
4944 0 : return NT_STATUS_NO_MEMORY;
4945 : }
4946 :
4947 0 : status = smbldap_search_domain_info(smbldap_state, &result,
4948 : get_global_sam_name(), False);
4949 0 : if (!NT_STATUS_IS_OK(status)) {
4950 0 : DEBUG(3, ("Could not get domain info: %s\n",
4951 : nt_errstr(status)));
4952 0 : goto done;
4953 : }
4954 :
4955 0 : smbldap_talloc_autofree_ldapmsg(mem_ctx, result);
4956 :
4957 0 : entry = ldap_first_entry(priv2ld(priv), result);
4958 0 : if (entry == NULL) {
4959 0 : DEBUG(0, ("Could not get domain info entry\n"));
4960 0 : status = NT_STATUS_INTERNAL_DB_CORRUPTION;
4961 0 : goto done;
4962 : }
4963 :
4964 : /* Find the largest of the three attributes "sambaNextRid",
4965 : "sambaNextGroupRid" and "sambaNextUserRid". I gave up on the
4966 : concept of differentiating between user and group rids, and will
4967 : use only "sambaNextRid" in the future. But for compatibility
4968 : reasons I look if others have chosen different strategies -- VL */
4969 :
4970 0 : value = smbldap_talloc_single_attribute(priv2ld(priv), entry,
4971 : "sambaNextRid", mem_ctx);
4972 0 : if (value != NULL) {
4973 0 : tmp = (uint32_t)smb_strtoul(value,
4974 : NULL,
4975 : 10,
4976 : &error,
4977 : SMB_STR_STANDARD);
4978 0 : if (error != 0) {
4979 0 : goto done;
4980 : }
4981 :
4982 0 : nextRid = MAX(nextRid, tmp);
4983 : }
4984 :
4985 0 : value = smbldap_talloc_single_attribute(priv2ld(priv), entry,
4986 : "sambaNextUserRid", mem_ctx);
4987 0 : if (value != NULL) {
4988 0 : tmp = (uint32_t)smb_strtoul(value,
4989 : NULL,
4990 : 10,
4991 : &error,
4992 : SMB_STR_STANDARD);
4993 0 : if (error != 0) {
4994 0 : goto done;
4995 : }
4996 :
4997 0 : nextRid = MAX(nextRid, tmp);
4998 : }
4999 :
5000 0 : value = smbldap_talloc_single_attribute(priv2ld(priv), entry,
5001 : "sambaNextGroupRid", mem_ctx);
5002 0 : if (value != NULL) {
5003 0 : tmp = (uint32_t)smb_strtoul(value,
5004 : NULL,
5005 : 10,
5006 : &error,
5007 : SMB_STR_STANDARD);
5008 0 : if (error != 0) {
5009 0 : goto done;
5010 : }
5011 :
5012 0 : nextRid = MAX(nextRid, tmp);
5013 : }
5014 :
5015 0 : if (nextRid == 0) {
5016 0 : nextRid = BASE_RID-1;
5017 : }
5018 :
5019 0 : nextRid += 1;
5020 :
5021 0 : smbldap_make_mod(priv2ld(priv), entry, &mods, "sambaNextRid",
5022 0 : talloc_asprintf(mem_ctx, "%d", nextRid));
5023 0 : smbldap_talloc_autofree_ldapmod(mem_ctx, mods);
5024 :
5025 0 : if ((dn = smbldap_talloc_dn(mem_ctx, priv2ld(priv), entry)) == NULL) {
5026 0 : status = NT_STATUS_NO_MEMORY;
5027 0 : goto done;
5028 : }
5029 :
5030 0 : rc = smbldap_modify(smbldap_state, dn, mods);
5031 :
5032 : /* ACCESS_DENIED is used as a placeholder for "the modify failed,
5033 : * please retry" */
5034 :
5035 0 : status = (rc == LDAP_SUCCESS) ? NT_STATUS_OK : NT_STATUS_ACCESS_DENIED;
5036 :
5037 0 : done:
5038 0 : if (NT_STATUS_IS_OK(status)) {
5039 0 : *rid = nextRid;
5040 : }
5041 :
5042 0 : TALLOC_FREE(mem_ctx);
5043 0 : return status;
5044 : }
5045 :
5046 0 : static NTSTATUS ldapsam_new_rid_internal(struct pdb_methods *methods, uint32_t *rid)
5047 : {
5048 0 : int i;
5049 :
5050 0 : for (i=0; i<10; i++) {
5051 0 : NTSTATUS result = ldapsam_get_new_rid(
5052 0 : (struct ldapsam_privates *)methods->private_data, rid);
5053 0 : if (NT_STATUS_IS_OK(result)) {
5054 0 : return result;
5055 : }
5056 :
5057 0 : if (!NT_STATUS_EQUAL(result, NT_STATUS_ACCESS_DENIED)) {
5058 0 : return result;
5059 : }
5060 :
5061 : /* The ldap update failed (maybe a race condition), retry */
5062 : }
5063 :
5064 : /* Tried 10 times, fail. */
5065 0 : return NT_STATUS_ACCESS_DENIED;
5066 : }
5067 :
5068 0 : static bool ldapsam_new_rid(struct pdb_methods *methods, uint32_t *rid)
5069 : {
5070 0 : NTSTATUS result = ldapsam_new_rid_internal(methods, rid);
5071 0 : return NT_STATUS_IS_OK(result) ? True : False;
5072 : }
5073 :
5074 0 : static bool ldapsam_sid_to_id(struct pdb_methods *methods,
5075 : const struct dom_sid *sid,
5076 : struct unixid *id)
5077 : {
5078 0 : struct ldapsam_privates *priv =
5079 : (struct ldapsam_privates *)methods->private_data;
5080 0 : char *filter;
5081 0 : int error = 0;
5082 0 : struct dom_sid_buf buf;
5083 0 : const char *attrs[] = { "sambaGroupType", "gidNumber", "uidNumber",
5084 : NULL };
5085 0 : LDAPMessage *result = NULL;
5086 0 : LDAPMessage *entry = NULL;
5087 0 : bool ret = False;
5088 0 : char *value;
5089 0 : int rc;
5090 :
5091 0 : TALLOC_CTX *mem_ctx;
5092 :
5093 0 : ret = pdb_sid_to_id_unix_users_and_groups(sid, id);
5094 0 : if (ret == true) {
5095 0 : return true;
5096 : }
5097 :
5098 0 : mem_ctx = talloc_new(NULL);
5099 0 : if (mem_ctx == NULL) {
5100 0 : DEBUG(0, ("talloc_new failed\n"));
5101 0 : return False;
5102 : }
5103 :
5104 0 : filter = talloc_asprintf(mem_ctx,
5105 : "(&(sambaSid=%s)"
5106 : "(|(objectClass="LDAP_OBJ_GROUPMAP")(objectClass="LDAP_OBJ_SAMBASAMACCOUNT")))",
5107 : dom_sid_str_buf(sid, &buf));
5108 0 : if (filter == NULL) {
5109 0 : DEBUG(5, ("talloc_asprintf failed\n"));
5110 0 : goto done;
5111 : }
5112 :
5113 0 : rc = smbldap_search_suffix(priv->smbldap_state, filter,
5114 : attrs, &result);
5115 0 : if (rc != LDAP_SUCCESS) {
5116 0 : goto done;
5117 : }
5118 0 : smbldap_talloc_autofree_ldapmsg(mem_ctx, result);
5119 :
5120 0 : if (ldap_count_entries(priv2ld(priv), result) != 1) {
5121 0 : DEBUG(10, ("Got %d entries, expected one\n",
5122 : ldap_count_entries(priv2ld(priv), result)));
5123 0 : goto done;
5124 : }
5125 :
5126 0 : entry = ldap_first_entry(priv2ld(priv), result);
5127 :
5128 0 : value = smbldap_talloc_single_attribute(priv2ld(priv), entry,
5129 : "sambaGroupType", mem_ctx);
5130 :
5131 0 : if (value != NULL) {
5132 0 : const char *gid_str;
5133 : /* It's a group */
5134 :
5135 0 : gid_str = smbldap_talloc_single_attribute(
5136 : priv2ld(priv), entry, "gidNumber", mem_ctx);
5137 0 : if (gid_str == NULL) {
5138 0 : DEBUG(1, ("%s has sambaGroupType but no gidNumber\n",
5139 : smbldap_talloc_dn(mem_ctx, priv2ld(priv),
5140 : entry)));
5141 0 : goto done;
5142 : }
5143 :
5144 0 : id->id = smb_strtoul(gid_str,
5145 : NULL,
5146 : 10,
5147 : &error,
5148 : SMB_STR_STANDARD);
5149 0 : if (error != 0) {
5150 0 : goto done;
5151 : }
5152 :
5153 0 : id->type = ID_TYPE_GID;
5154 0 : ret = True;
5155 0 : goto done;
5156 : }
5157 :
5158 : /* It must be a user */
5159 :
5160 0 : value = smbldap_talloc_single_attribute(priv2ld(priv), entry,
5161 : "uidNumber", mem_ctx);
5162 0 : if (value == NULL) {
5163 0 : DEBUG(1, ("Could not find uidNumber in %s\n",
5164 : smbldap_talloc_dn(mem_ctx, priv2ld(priv), entry)));
5165 0 : goto done;
5166 : }
5167 :
5168 0 : id->id = smb_strtoul(value, NULL, 10, &error, SMB_STR_STANDARD);
5169 0 : if (error != 0) {
5170 0 : goto done;
5171 : }
5172 :
5173 0 : id->type = ID_TYPE_UID;
5174 0 : ret = True;
5175 0 : done:
5176 0 : TALLOC_FREE(mem_ctx);
5177 0 : return ret;
5178 : }
5179 :
5180 : /**
5181 : * Find the SID for a uid.
5182 : * This is shortcut is only used if ldapsam:trusted is set to true.
5183 : */
5184 0 : static bool ldapsam_uid_to_sid(struct pdb_methods *methods, uid_t uid,
5185 : struct dom_sid *sid)
5186 : {
5187 0 : struct ldapsam_privates *priv =
5188 : (struct ldapsam_privates *)methods->private_data;
5189 0 : char *filter;
5190 0 : const char *attrs[] = { "sambaSID", NULL };
5191 0 : LDAPMessage *result = NULL;
5192 0 : LDAPMessage *entry = NULL;
5193 0 : bool ret = false;
5194 0 : char *user_sid_string;
5195 0 : struct dom_sid user_sid;
5196 0 : int rc;
5197 0 : TALLOC_CTX *tmp_ctx = talloc_stackframe();
5198 :
5199 0 : filter = talloc_asprintf(tmp_ctx,
5200 : "(&(uidNumber=%u)"
5201 : "(objectClass="LDAP_OBJ_POSIXACCOUNT")"
5202 : "(objectClass="LDAP_OBJ_SAMBASAMACCOUNT"))",
5203 : (unsigned int)uid);
5204 0 : if (filter == NULL) {
5205 0 : DEBUG(3, ("talloc_asprintf failed\n"));
5206 0 : goto done;
5207 : }
5208 :
5209 0 : rc = smbldap_search_suffix(priv->smbldap_state, filter, attrs, &result);
5210 0 : if (rc != LDAP_SUCCESS) {
5211 0 : goto done;
5212 : }
5213 0 : smbldap_talloc_autofree_ldapmsg(tmp_ctx, result);
5214 :
5215 0 : if (ldap_count_entries(priv2ld(priv), result) != 1) {
5216 0 : DEBUG(3, ("ERROR: Got %d entries for uid %u, expected one\n",
5217 : ldap_count_entries(priv2ld(priv), result),
5218 : (unsigned int)uid));
5219 0 : goto done;
5220 : }
5221 :
5222 0 : entry = ldap_first_entry(priv2ld(priv), result);
5223 :
5224 0 : user_sid_string = smbldap_talloc_single_attribute(priv2ld(priv), entry,
5225 : "sambaSID", tmp_ctx);
5226 0 : if (user_sid_string == NULL) {
5227 0 : DEBUG(1, ("Could not find sambaSID in object '%s'\n",
5228 : smbldap_talloc_dn(tmp_ctx, priv2ld(priv), entry)));
5229 0 : goto done;
5230 : }
5231 :
5232 0 : if (!string_to_sid(&user_sid, user_sid_string)) {
5233 0 : DEBUG(3, ("Error calling string_to_sid for sid '%s'\n",
5234 : user_sid_string));
5235 0 : goto done;
5236 : }
5237 :
5238 0 : sid_copy(sid, &user_sid);
5239 :
5240 0 : ret = true;
5241 :
5242 0 : done:
5243 0 : TALLOC_FREE(tmp_ctx);
5244 0 : return ret;
5245 : }
5246 :
5247 : /**
5248 : * Find the SID for a gid.
5249 : * This is shortcut is only used if ldapsam:trusted is set to true.
5250 : */
5251 0 : static bool ldapsam_gid_to_sid(struct pdb_methods *methods, gid_t gid,
5252 : struct dom_sid *sid)
5253 : {
5254 0 : struct ldapsam_privates *priv =
5255 : (struct ldapsam_privates *)methods->private_data;
5256 0 : char *filter;
5257 0 : const char *attrs[] = { "sambaSID", NULL };
5258 0 : LDAPMessage *result = NULL;
5259 0 : LDAPMessage *entry = NULL;
5260 0 : bool ret = false;
5261 0 : char *group_sid_string;
5262 0 : struct dom_sid group_sid;
5263 0 : int rc;
5264 0 : TALLOC_CTX *tmp_ctx = talloc_stackframe();
5265 :
5266 0 : filter = talloc_asprintf(tmp_ctx,
5267 : "(&(gidNumber=%u)"
5268 : "(objectClass="LDAP_OBJ_GROUPMAP"))",
5269 : (unsigned int)gid);
5270 0 : if (filter == NULL) {
5271 0 : DEBUG(3, ("talloc_asprintf failed\n"));
5272 0 : goto done;
5273 : }
5274 :
5275 0 : rc = smbldap_search_suffix(priv->smbldap_state, filter, attrs, &result);
5276 0 : if (rc != LDAP_SUCCESS) {
5277 0 : goto done;
5278 : }
5279 0 : smbldap_talloc_autofree_ldapmsg(tmp_ctx, result);
5280 :
5281 0 : if (ldap_count_entries(priv2ld(priv), result) != 1) {
5282 0 : DEBUG(3, ("ERROR: Got %d entries for gid %u, expected one\n",
5283 : ldap_count_entries(priv2ld(priv), result),
5284 : (unsigned int)gid));
5285 0 : goto done;
5286 : }
5287 :
5288 0 : entry = ldap_first_entry(priv2ld(priv), result);
5289 :
5290 0 : group_sid_string = smbldap_talloc_single_attribute(priv2ld(priv), entry,
5291 : "sambaSID", tmp_ctx);
5292 0 : if (group_sid_string == NULL) {
5293 0 : DEBUG(1, ("Could not find sambaSID in object '%s'\n",
5294 : smbldap_talloc_dn(tmp_ctx, priv2ld(priv), entry)));
5295 0 : goto done;
5296 : }
5297 :
5298 0 : if (!string_to_sid(&group_sid, group_sid_string)) {
5299 0 : DEBUG(3, ("Error calling string_to_sid for sid '%s'\n",
5300 : group_sid_string));
5301 0 : goto done;
5302 : }
5303 :
5304 0 : sid_copy(sid, &group_sid);
5305 :
5306 0 : ret = true;
5307 :
5308 0 : done:
5309 0 : TALLOC_FREE(tmp_ctx);
5310 0 : return ret;
5311 : }
5312 :
5313 0 : static bool ldapsam_id_to_sid(struct pdb_methods *methods, struct unixid *id,
5314 : struct dom_sid *sid)
5315 : {
5316 0 : switch (id->type) {
5317 0 : case ID_TYPE_UID:
5318 0 : return ldapsam_uid_to_sid(methods, id->id, sid);
5319 :
5320 0 : case ID_TYPE_GID:
5321 0 : return ldapsam_gid_to_sid(methods, id->id, sid);
5322 :
5323 0 : default:
5324 0 : return false;
5325 : }
5326 : }
5327 :
5328 :
5329 : /*
5330 : * The following functions are called only if
5331 : * ldapsam:trusted and ldapsam:editposix are
5332 : * set to true
5333 : */
5334 :
5335 : /*
5336 : * ldapsam_create_user creates a new
5337 : * posixAccount and sambaSamAccount object
5338 : * in the ldap users subtree
5339 : *
5340 : * The uid is allocated by winbindd.
5341 : */
5342 :
5343 0 : static NTSTATUS ldapsam_create_user(struct pdb_methods *my_methods,
5344 : TALLOC_CTX *tmp_ctx, const char *name,
5345 : uint32_t acb_info, uint32_t *rid)
5346 : {
5347 0 : struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
5348 0 : LDAPMessage *entry = NULL;
5349 0 : LDAPMessage *result = NULL;
5350 0 : uint32_t num_result;
5351 0 : bool is_machine = False;
5352 0 : bool add_posix = False;
5353 0 : bool init_okay = False;
5354 0 : LDAPMod **mods = NULL;
5355 0 : struct samu *user;
5356 0 : char *filter;
5357 0 : char *username;
5358 0 : char *homedir;
5359 0 : char *gidstr;
5360 0 : char *uidstr;
5361 0 : char *shell;
5362 0 : const char *dn = NULL;
5363 0 : struct dom_sid group_sid;
5364 0 : struct dom_sid user_sid;
5365 0 : gid_t gid = -1;
5366 0 : uid_t uid = -1;
5367 0 : NTSTATUS ret;
5368 0 : int rc;
5369 :
5370 0 : if (((acb_info & ACB_NORMAL) && name[strlen(name)-1] == '$') ||
5371 0 : acb_info & ACB_WSTRUST ||
5372 0 : acb_info & ACB_SVRTRUST ||
5373 0 : acb_info & ACB_DOMTRUST) {
5374 0 : is_machine = True;
5375 : }
5376 :
5377 0 : username = escape_ldap_string(talloc_tos(), name);
5378 0 : filter = talloc_asprintf(tmp_ctx, "(&(uid=%s)(objectClass="LDAP_OBJ_POSIXACCOUNT"))",
5379 : username);
5380 0 : TALLOC_FREE(username);
5381 :
5382 0 : rc = smbldap_search_suffix(ldap_state->smbldap_state, filter, NULL, &result);
5383 0 : if (rc != LDAP_SUCCESS) {
5384 0 : DEBUG(0,("ldapsam_create_user: ldap search failed!\n"));
5385 0 : return NT_STATUS_ACCESS_DENIED;
5386 : }
5387 0 : smbldap_talloc_autofree_ldapmsg(tmp_ctx, result);
5388 :
5389 0 : num_result = ldap_count_entries(priv2ld(ldap_state), result);
5390 :
5391 0 : if (num_result > 1) {
5392 0 : DEBUG (0, ("ldapsam_create_user: More than one user with name [%s] ?!\n", name));
5393 0 : return NT_STATUS_INTERNAL_DB_CORRUPTION;
5394 : }
5395 :
5396 0 : if (num_result == 1) {
5397 0 : char *tmp;
5398 : /* check if it is just a posix account.
5399 : * or if there is a sid attached to this entry
5400 : */
5401 :
5402 0 : entry = ldap_first_entry(priv2ld(ldap_state), result);
5403 0 : if (!entry) {
5404 0 : return NT_STATUS_UNSUCCESSFUL;
5405 : }
5406 :
5407 0 : tmp = smbldap_talloc_single_attribute(priv2ld(ldap_state), entry, "sambaSID", tmp_ctx);
5408 0 : if (tmp) {
5409 0 : DEBUG (1, ("ldapsam_create_user: The user [%s] already exist!\n", name));
5410 0 : return NT_STATUS_USER_EXISTS;
5411 : }
5412 :
5413 : /* it is just a posix account, retrieve the dn for later use */
5414 0 : dn = smbldap_talloc_dn(tmp_ctx, priv2ld(ldap_state), entry);
5415 0 : if (!dn) {
5416 0 : DEBUG(0,("ldapsam_create_user: Out of memory!\n"));
5417 0 : return NT_STATUS_NO_MEMORY;
5418 : }
5419 : }
5420 :
5421 0 : if (num_result == 0) {
5422 0 : add_posix = True;
5423 : }
5424 :
5425 : /* Create the basic samu structure and generate the mods for the ldap commit */
5426 0 : if (!NT_STATUS_IS_OK((ret = ldapsam_new_rid_internal(my_methods, rid)))) {
5427 0 : DEBUG(1, ("ldapsam_create_user: Could not allocate a new RID\n"));
5428 0 : return ret;
5429 : }
5430 :
5431 0 : sid_compose(&user_sid, get_global_sam_sid(), *rid);
5432 :
5433 0 : user = samu_new(tmp_ctx);
5434 0 : if (!user) {
5435 0 : DEBUG(1,("ldapsam_create_user: Unable to allocate user struct\n"));
5436 0 : return NT_STATUS_NO_MEMORY;
5437 : }
5438 :
5439 0 : if (!pdb_set_username(user, name, PDB_SET)) {
5440 0 : DEBUG(1,("ldapsam_create_user: Unable to fill user structs\n"));
5441 0 : return NT_STATUS_UNSUCCESSFUL;
5442 : }
5443 0 : if (!pdb_set_domain(user, get_global_sam_name(), PDB_SET)) {
5444 0 : DEBUG(1,("ldapsam_create_user: Unable to fill user structs\n"));
5445 0 : return NT_STATUS_UNSUCCESSFUL;
5446 : }
5447 0 : if (is_machine) {
5448 0 : if (acb_info & ACB_NORMAL) {
5449 0 : if (!pdb_set_acct_ctrl(user, ACB_WSTRUST, PDB_SET)) {
5450 0 : DEBUG(1,("ldapsam_create_user: Unable to fill user structs\n"));
5451 0 : return NT_STATUS_UNSUCCESSFUL;
5452 : }
5453 : } else {
5454 0 : if (!pdb_set_acct_ctrl(user, acb_info, PDB_SET)) {
5455 0 : DEBUG(1,("ldapsam_create_user: Unable to fill user structs\n"));
5456 0 : return NT_STATUS_UNSUCCESSFUL;
5457 : }
5458 : }
5459 : } else {
5460 0 : if (!pdb_set_acct_ctrl(user, ACB_NORMAL | ACB_DISABLED, PDB_SET)) {
5461 0 : DEBUG(1,("ldapsam_create_user: Unable to fill user structs\n"));
5462 0 : return NT_STATUS_UNSUCCESSFUL;
5463 : }
5464 : }
5465 :
5466 0 : if (!pdb_set_user_sid(user, &user_sid, PDB_SET)) {
5467 0 : DEBUG(1,("ldapsam_create_user: Unable to fill user structs\n"));
5468 0 : return NT_STATUS_UNSUCCESSFUL;
5469 : }
5470 :
5471 0 : init_okay = init_ldap_from_sam(ldap_state, entry, &mods, user, pdb_element_is_set_or_changed);
5472 :
5473 0 : if (!init_okay) {
5474 0 : DEBUG(1,("ldapsam_create_user: Unable to fill user structs\n"));
5475 0 : ldap_mods_free(mods, true);
5476 0 : return NT_STATUS_UNSUCCESSFUL;
5477 : }
5478 :
5479 0 : if (ldap_state->schema_ver != SCHEMAVER_SAMBASAMACCOUNT) {
5480 0 : DEBUG(1,("ldapsam_create_user: Unsupported schema version\n"));
5481 : }
5482 0 : smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectClass", LDAP_OBJ_SAMBASAMACCOUNT);
5483 :
5484 0 : if (add_posix) {
5485 0 : char *escape_name;
5486 :
5487 0 : DEBUG(3,("ldapsam_create_user: Creating new posix user\n"));
5488 :
5489 : /* retrieve the Domain Users group gid */
5490 0 : if (!sid_compose(&group_sid, get_global_sam_sid(), DOMAIN_RID_USERS) ||
5491 0 : !sid_to_gid(&group_sid, &gid)) {
5492 0 : DEBUG (0, ("ldapsam_create_user: Unable to get the Domain Users gid: bailing out!\n"));
5493 0 : ldap_mods_free(mods, true);
5494 0 : return NT_STATUS_INVALID_PRIMARY_GROUP;
5495 : }
5496 :
5497 : /* lets allocate a new userid for this user */
5498 0 : if (!winbind_allocate_uid(&uid)) {
5499 0 : DEBUG (0, ("ldapsam_create_user: Unable to allocate a new user id: bailing out!\n"));
5500 0 : ldap_mods_free(mods, true);
5501 0 : return NT_STATUS_UNSUCCESSFUL;
5502 : }
5503 :
5504 :
5505 0 : if (is_machine) {
5506 : /* TODO: choose a more appropriate default for machines */
5507 0 : homedir = talloc_sub_specified(tmp_ctx,
5508 : lp_template_homedir(),
5509 : "SMB_workstations_home",
5510 : NULL,
5511 : ldap_state->domain_name,
5512 : uid,
5513 : gid);
5514 0 : shell = talloc_strdup(tmp_ctx, "/bin/false");
5515 : } else {
5516 0 : homedir = talloc_sub_specified(tmp_ctx,
5517 : lp_template_homedir(),
5518 : name,
5519 : NULL,
5520 : ldap_state->domain_name,
5521 : uid,
5522 : gid);
5523 0 : shell = talloc_sub_specified(tmp_ctx,
5524 : lp_template_shell(),
5525 : name,
5526 : NULL,
5527 : ldap_state->domain_name,
5528 : uid,
5529 : gid);
5530 : }
5531 0 : uidstr = talloc_asprintf(tmp_ctx, "%u", (unsigned int)uid);
5532 0 : gidstr = talloc_asprintf(tmp_ctx, "%u", (unsigned int)gid);
5533 :
5534 0 : escape_name = escape_rdn_val_string_alloc(name);
5535 0 : if (!escape_name) {
5536 0 : DEBUG (0, ("ldapsam_create_user: Out of memory!\n"));
5537 0 : ldap_mods_free(mods, true);
5538 0 : return NT_STATUS_NO_MEMORY;
5539 : }
5540 :
5541 0 : if (is_machine) {
5542 0 : dn = talloc_asprintf(tmp_ctx, "uid=%s,%s", escape_name, lp_ldap_machine_suffix (talloc_tos()));
5543 : } else {
5544 0 : dn = talloc_asprintf(tmp_ctx, "uid=%s,%s", escape_name, lp_ldap_user_suffix (talloc_tos()));
5545 : }
5546 :
5547 0 : SAFE_FREE(escape_name);
5548 :
5549 0 : if (!homedir || !shell || !uidstr || !gidstr || !dn) {
5550 0 : DEBUG (0, ("ldapsam_create_user: Out of memory!\n"));
5551 0 : ldap_mods_free(mods, true);
5552 0 : return NT_STATUS_NO_MEMORY;
5553 : }
5554 :
5555 0 : smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectClass", LDAP_OBJ_ACCOUNT);
5556 0 : smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectClass", LDAP_OBJ_POSIXACCOUNT);
5557 0 : smbldap_set_mod(&mods, LDAP_MOD_ADD, "cn", name);
5558 0 : smbldap_set_mod(&mods, LDAP_MOD_ADD, "uidNumber", uidstr);
5559 0 : smbldap_set_mod(&mods, LDAP_MOD_ADD, "gidNumber", gidstr);
5560 0 : smbldap_set_mod(&mods, LDAP_MOD_ADD, "homeDirectory", homedir);
5561 0 : smbldap_set_mod(&mods, LDAP_MOD_ADD, "loginShell", shell);
5562 : }
5563 :
5564 0 : if (add_posix) {
5565 0 : rc = smbldap_add(ldap_state->smbldap_state, dn, mods);
5566 : } else {
5567 0 : rc = smbldap_modify(ldap_state->smbldap_state, dn, mods);
5568 : }
5569 :
5570 0 : ldap_mods_free(mods, true);
5571 :
5572 0 : if (rc != LDAP_SUCCESS) {
5573 0 : DEBUG(0,("ldapsam_create_user: failed to create a new user [%s] (dn = %s)\n", name ,dn));
5574 0 : return NT_STATUS_UNSUCCESSFUL;
5575 : }
5576 :
5577 0 : DEBUG(2,("ldapsam_create_user: added account [%s] in the LDAP database\n", name));
5578 :
5579 0 : flush_pwnam_cache();
5580 :
5581 0 : return NT_STATUS_OK;
5582 : }
5583 :
5584 0 : static NTSTATUS ldapsam_delete_user(struct pdb_methods *my_methods, TALLOC_CTX *tmp_ctx, struct samu *sam_acct)
5585 : {
5586 0 : struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
5587 0 : LDAPMessage *result = NULL;
5588 0 : LDAPMessage *entry = NULL;
5589 0 : int num_result;
5590 0 : const char *dn;
5591 0 : char *filter;
5592 0 : int rc;
5593 :
5594 0 : DEBUG(0,("ldapsam_delete_user: Attempt to delete user [%s]\n", pdb_get_username(sam_acct)));
5595 :
5596 0 : filter = talloc_asprintf(tmp_ctx,
5597 : "(&(uid=%s)"
5598 : "(objectClass="LDAP_OBJ_POSIXACCOUNT")"
5599 : "(objectClass="LDAP_OBJ_SAMBASAMACCOUNT"))",
5600 : pdb_get_username(sam_acct));
5601 0 : if (filter == NULL) {
5602 0 : return NT_STATUS_NO_MEMORY;
5603 : }
5604 :
5605 0 : rc = smbldap_search_suffix(ldap_state->smbldap_state, filter, NULL, &result);
5606 0 : if (rc != LDAP_SUCCESS) {
5607 0 : DEBUG(0,("ldapsam_delete_user: user search failed!\n"));
5608 0 : return NT_STATUS_UNSUCCESSFUL;
5609 : }
5610 0 : smbldap_talloc_autofree_ldapmsg(tmp_ctx, result);
5611 :
5612 0 : num_result = ldap_count_entries(priv2ld(ldap_state), result);
5613 :
5614 0 : if (num_result == 0) {
5615 0 : DEBUG(0,("ldapsam_delete_user: user not found!\n"));
5616 0 : return NT_STATUS_NO_SUCH_USER;
5617 : }
5618 :
5619 0 : if (num_result > 1) {
5620 0 : DEBUG (0, ("ldapsam_delete_user: More than one user with name [%s] ?!\n", pdb_get_username(sam_acct)));
5621 0 : return NT_STATUS_INTERNAL_DB_CORRUPTION;
5622 : }
5623 :
5624 0 : entry = ldap_first_entry(priv2ld(ldap_state), result);
5625 0 : if (!entry) {
5626 0 : return NT_STATUS_UNSUCCESSFUL;
5627 : }
5628 :
5629 : /* it is just a posix account, retrieve the dn for later use */
5630 0 : dn = smbldap_talloc_dn(tmp_ctx, priv2ld(ldap_state), entry);
5631 0 : if (!dn) {
5632 0 : DEBUG(0,("ldapsam_delete_user: Out of memory!\n"));
5633 0 : return NT_STATUS_NO_MEMORY;
5634 : }
5635 :
5636 : /* try to remove memberships first */
5637 : {
5638 0 : NTSTATUS status;
5639 0 : struct dom_sid *sids = NULL;
5640 0 : gid_t *gids = NULL;
5641 0 : uint32_t num_groups = 0;
5642 0 : int i;
5643 0 : uint32_t user_rid = pdb_get_user_rid(sam_acct);
5644 :
5645 0 : status = ldapsam_enum_group_memberships(my_methods,
5646 : tmp_ctx,
5647 : sam_acct,
5648 : &sids,
5649 : &gids,
5650 : &num_groups);
5651 0 : if (!NT_STATUS_IS_OK(status)) {
5652 0 : goto delete_dn;
5653 : }
5654 :
5655 0 : for (i=0; i < num_groups; i++) {
5656 :
5657 0 : uint32_t group_rid;
5658 :
5659 0 : sid_peek_rid(&sids[i], &group_rid);
5660 :
5661 0 : ldapsam_del_groupmem(my_methods,
5662 : tmp_ctx,
5663 : group_rid,
5664 : user_rid);
5665 : }
5666 : }
5667 :
5668 0 : delete_dn:
5669 :
5670 0 : rc = smbldap_delete(ldap_state->smbldap_state, dn);
5671 0 : if (rc != LDAP_SUCCESS) {
5672 0 : return NT_STATUS_UNSUCCESSFUL;
5673 : }
5674 :
5675 0 : flush_pwnam_cache();
5676 :
5677 0 : return NT_STATUS_OK;
5678 : }
5679 :
5680 : /*
5681 : * ldapsam_create_group creates a new
5682 : * posixGroup and sambaGroupMapping object
5683 : * in the ldap groups subtree
5684 : *
5685 : * The gid is allocated by winbindd.
5686 : */
5687 :
5688 0 : static NTSTATUS ldapsam_create_dom_group(struct pdb_methods *my_methods,
5689 : TALLOC_CTX *tmp_ctx,
5690 : const char *name,
5691 : uint32_t *rid)
5692 : {
5693 0 : struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
5694 0 : NTSTATUS ret;
5695 0 : LDAPMessage *entry = NULL;
5696 0 : LDAPMessage *result = NULL;
5697 0 : uint32_t num_result;
5698 0 : bool is_new_entry = False;
5699 0 : LDAPMod **mods = NULL;
5700 0 : char *filter;
5701 0 : char *groupname;
5702 0 : const char *grouptype;
5703 0 : char *gidstr;
5704 0 : const char *dn = NULL;
5705 0 : struct dom_sid group_sid;
5706 0 : struct dom_sid_buf buf;
5707 0 : gid_t gid = -1;
5708 0 : int rc;
5709 0 : int error = 0;
5710 :
5711 0 : groupname = escape_ldap_string(talloc_tos(), name);
5712 0 : filter = talloc_asprintf(tmp_ctx, "(&(cn=%s)(objectClass="LDAP_OBJ_POSIXGROUP"))",
5713 : groupname);
5714 0 : TALLOC_FREE(groupname);
5715 :
5716 0 : rc = smbldap_search_suffix(ldap_state->smbldap_state, filter, NULL, &result);
5717 0 : if (rc != LDAP_SUCCESS) {
5718 0 : DEBUG(0,("ldapsam_create_group: ldap search failed!\n"));
5719 0 : return NT_STATUS_UNSUCCESSFUL;
5720 : }
5721 0 : smbldap_talloc_autofree_ldapmsg(tmp_ctx, result);
5722 :
5723 0 : num_result = ldap_count_entries(priv2ld(ldap_state), result);
5724 :
5725 0 : if (num_result > 1) {
5726 0 : DEBUG (0, ("ldapsam_create_group: There exists more than one group with name [%s]: bailing out!\n", name));
5727 0 : return NT_STATUS_INTERNAL_DB_CORRUPTION;
5728 : }
5729 :
5730 0 : if (num_result == 1) {
5731 0 : char *tmp;
5732 : /* check if it is just a posix group.
5733 : * or if there is a sid attached to this entry
5734 : */
5735 :
5736 0 : entry = ldap_first_entry(priv2ld(ldap_state), result);
5737 0 : if (!entry) {
5738 0 : return NT_STATUS_UNSUCCESSFUL;
5739 : }
5740 :
5741 0 : tmp = smbldap_talloc_single_attribute(priv2ld(ldap_state), entry, "sambaSID", tmp_ctx);
5742 0 : if (tmp) {
5743 0 : DEBUG (1, ("ldapsam_create_group: The group [%s] already exist!\n", name));
5744 0 : return NT_STATUS_GROUP_EXISTS;
5745 : }
5746 :
5747 : /* it is just a posix group, retrieve the gid and the dn for later use */
5748 0 : tmp = smbldap_talloc_single_attribute(priv2ld(ldap_state), entry, "gidNumber", tmp_ctx);
5749 0 : if (!tmp) {
5750 0 : DEBUG (1, ("ldapsam_create_group: Couldn't retrieve the gidNumber for [%s]?!?!\n", name));
5751 0 : return NT_STATUS_INTERNAL_DB_CORRUPTION;
5752 : }
5753 :
5754 0 : gid = smb_strtoul(tmp, NULL, 10, &error, SMB_STR_STANDARD);
5755 0 : if (error != 0) {
5756 0 : DBG_ERR("Failed to convert gidNumber\n");
5757 0 : return NT_STATUS_UNSUCCESSFUL;
5758 : }
5759 :
5760 0 : dn = smbldap_talloc_dn(tmp_ctx, priv2ld(ldap_state), entry);
5761 0 : if (!dn) {
5762 0 : DEBUG(0,("ldapsam_create_group: Out of memory!\n"));
5763 0 : return NT_STATUS_NO_MEMORY;
5764 : }
5765 : }
5766 :
5767 0 : if (num_result == 0) {
5768 0 : is_new_entry = true;
5769 : }
5770 :
5771 0 : if (!NT_STATUS_IS_OK((ret = ldapsam_new_rid_internal(my_methods, rid)))) {
5772 0 : DEBUG(1, ("ldapsam_create_group: Could not allocate a new RID\n"));
5773 0 : return ret;
5774 : }
5775 :
5776 0 : sid_compose(&group_sid, get_global_sam_sid(), *rid);
5777 :
5778 0 : grouptype = talloc_asprintf(tmp_ctx, "%d", SID_NAME_DOM_GRP);
5779 :
5780 0 : if (!grouptype) {
5781 0 : DEBUG(0,("ldapsam_create_group: Out of memory!\n"));
5782 0 : return NT_STATUS_NO_MEMORY;
5783 : }
5784 :
5785 0 : smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectClass", LDAP_OBJ_GROUPMAP);
5786 0 : smbldap_set_mod(&mods,
5787 : LDAP_MOD_ADD,
5788 : "sambaSid",
5789 0 : dom_sid_str_buf(&group_sid, &buf));
5790 0 : smbldap_set_mod(&mods, LDAP_MOD_ADD, "sambaGroupType", grouptype);
5791 0 : smbldap_set_mod(&mods, LDAP_MOD_ADD, "displayName", name);
5792 :
5793 0 : if (is_new_entry) {
5794 0 : char *escape_name;
5795 :
5796 0 : DEBUG(3,("ldapsam_create_user: Creating new posix group\n"));
5797 :
5798 : /* lets allocate a new groupid for this group */
5799 0 : if (!winbind_allocate_gid(&gid)) {
5800 0 : DEBUG (0, ("ldapsam_create_group: Unable to allocate a new group id: bailing out!\n"));
5801 0 : return NT_STATUS_UNSUCCESSFUL;
5802 : }
5803 :
5804 0 : gidstr = talloc_asprintf(tmp_ctx, "%u", (unsigned int)gid);
5805 :
5806 0 : escape_name = escape_rdn_val_string_alloc(name);
5807 0 : if (!escape_name) {
5808 0 : DEBUG (0, ("ldapsam_create_group: Out of memory!\n"));
5809 0 : return NT_STATUS_NO_MEMORY;
5810 : }
5811 :
5812 0 : dn = talloc_asprintf(tmp_ctx, "cn=%s,%s", escape_name, lp_ldap_group_suffix(talloc_tos()));
5813 :
5814 0 : SAFE_FREE(escape_name);
5815 :
5816 0 : if (!gidstr || !dn) {
5817 0 : DEBUG (0, ("ldapsam_create_group: Out of memory!\n"));
5818 0 : return NT_STATUS_NO_MEMORY;
5819 : }
5820 :
5821 0 : smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectclass", LDAP_OBJ_POSIXGROUP);
5822 0 : smbldap_set_mod(&mods, LDAP_MOD_ADD, "cn", name);
5823 0 : smbldap_set_mod(&mods, LDAP_MOD_ADD, "gidNumber", gidstr);
5824 : }
5825 :
5826 0 : smbldap_talloc_autofree_ldapmod(tmp_ctx, mods);
5827 :
5828 0 : if (is_new_entry) {
5829 0 : rc = smbldap_add(ldap_state->smbldap_state, dn, mods);
5830 : #if 0
5831 : if (rc == LDAP_OBJECT_CLASS_VIOLATION) {
5832 : /* This call may fail with rfc2307bis schema */
5833 : /* Retry adding a structural class */
5834 : smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectClass", "????");
5835 : rc = smbldap_add(ldap_state->smbldap_state, dn, mods);
5836 : }
5837 : #endif
5838 : } else {
5839 0 : rc = smbldap_modify(ldap_state->smbldap_state, dn, mods);
5840 : }
5841 :
5842 0 : if (rc != LDAP_SUCCESS) {
5843 0 : DEBUG(0,("ldapsam_create_group: failed to create a new group [%s] (dn = %s)\n", name ,dn));
5844 0 : return NT_STATUS_UNSUCCESSFUL;
5845 : }
5846 :
5847 0 : DEBUG(2,("ldapsam_create_group: added group [%s] in the LDAP database\n", name));
5848 :
5849 0 : return NT_STATUS_OK;
5850 : }
5851 :
5852 0 : static NTSTATUS ldapsam_delete_dom_group(struct pdb_methods *my_methods, TALLOC_CTX *tmp_ctx, uint32_t rid)
5853 : {
5854 0 : struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
5855 0 : LDAPMessage *result = NULL;
5856 0 : LDAPMessage *entry = NULL;
5857 0 : int num_result;
5858 0 : const char *dn;
5859 0 : char *gidstr;
5860 0 : char *filter;
5861 0 : struct dom_sid group_sid;
5862 0 : struct dom_sid_buf buf;
5863 0 : int rc;
5864 :
5865 : /* get the group sid */
5866 0 : sid_compose(&group_sid, get_global_sam_sid(), rid);
5867 :
5868 0 : filter = talloc_asprintf(tmp_ctx,
5869 : "(&(sambaSID=%s)"
5870 : "(objectClass="LDAP_OBJ_POSIXGROUP")"
5871 : "(objectClass="LDAP_OBJ_GROUPMAP"))",
5872 : dom_sid_str_buf(&group_sid, &buf));
5873 0 : if (filter == NULL) {
5874 0 : return NT_STATUS_NO_MEMORY;
5875 : }
5876 :
5877 0 : rc = smbldap_search_suffix(ldap_state->smbldap_state, filter, NULL, &result);
5878 0 : if (rc != LDAP_SUCCESS) {
5879 0 : DEBUG(1,("ldapsam_delete_dom_group: group search failed!\n"));
5880 0 : return NT_STATUS_UNSUCCESSFUL;
5881 : }
5882 0 : smbldap_talloc_autofree_ldapmsg(tmp_ctx, result);
5883 :
5884 0 : num_result = ldap_count_entries(priv2ld(ldap_state), result);
5885 :
5886 0 : if (num_result == 0) {
5887 0 : DEBUG(1,("ldapsam_delete_dom_group: group not found!\n"));
5888 0 : return NT_STATUS_NO_SUCH_GROUP;
5889 : }
5890 :
5891 0 : if (num_result > 1) {
5892 0 : DEBUG (0, ("ldapsam_delete_dom_group: More than one group with the same SID ?!\n"));
5893 0 : return NT_STATUS_INTERNAL_DB_CORRUPTION;
5894 : }
5895 :
5896 0 : entry = ldap_first_entry(priv2ld(ldap_state), result);
5897 0 : if (!entry) {
5898 0 : return NT_STATUS_UNSUCCESSFUL;
5899 : }
5900 :
5901 : /* here it is, retrieve the dn for later use */
5902 0 : dn = smbldap_talloc_dn(tmp_ctx, priv2ld(ldap_state), entry);
5903 0 : if (!dn) {
5904 0 : DEBUG(0,("ldapsam_delete_dom_group: Out of memory!\n"));
5905 0 : return NT_STATUS_NO_MEMORY;
5906 : }
5907 :
5908 0 : gidstr = smbldap_talloc_single_attribute(priv2ld(ldap_state), entry, "gidNumber", tmp_ctx);
5909 0 : if (!gidstr) {
5910 0 : DEBUG (0, ("ldapsam_delete_dom_group: Unable to find the group's gid!\n"));
5911 0 : return NT_STATUS_INTERNAL_DB_CORRUPTION;
5912 : }
5913 :
5914 : /* check no user have this group marked as primary group */
5915 0 : filter = talloc_asprintf(tmp_ctx,
5916 : "(&(gidNumber=%s)"
5917 : "(objectClass="LDAP_OBJ_POSIXACCOUNT")"
5918 : "(objectClass="LDAP_OBJ_SAMBASAMACCOUNT"))",
5919 : gidstr);
5920 :
5921 0 : rc = smbldap_search_suffix(ldap_state->smbldap_state, filter, NULL, &result);
5922 0 : if (rc != LDAP_SUCCESS) {
5923 0 : DEBUG(1,("ldapsam_delete_dom_group: accounts search failed!\n"));
5924 0 : return NT_STATUS_UNSUCCESSFUL;
5925 : }
5926 0 : smbldap_talloc_autofree_ldapmsg(tmp_ctx, result);
5927 :
5928 0 : num_result = ldap_count_entries(priv2ld(ldap_state), result);
5929 :
5930 0 : if (num_result != 0) {
5931 0 : DEBUG(3,("ldapsam_delete_dom_group: Can't delete group, it is a primary group for %d users\n", num_result));
5932 0 : return NT_STATUS_MEMBERS_PRIMARY_GROUP;
5933 : }
5934 :
5935 0 : rc = smbldap_delete(ldap_state->smbldap_state, dn);
5936 0 : if (rc != LDAP_SUCCESS) {
5937 0 : return NT_STATUS_UNSUCCESSFUL;
5938 : }
5939 :
5940 0 : return NT_STATUS_OK;
5941 : }
5942 :
5943 0 : static NTSTATUS ldapsam_change_groupmem(struct pdb_methods *my_methods,
5944 : TALLOC_CTX *tmp_ctx,
5945 : uint32_t group_rid,
5946 : uint32_t member_rid,
5947 : int modop)
5948 : {
5949 0 : struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
5950 0 : LDAPMessage *entry = NULL;
5951 0 : LDAPMessage *result = NULL;
5952 0 : uint32_t num_result;
5953 0 : LDAPMod **mods = NULL;
5954 0 : char *filter;
5955 0 : char *uidstr;
5956 0 : const char *dn = NULL;
5957 0 : struct dom_sid group_sid;
5958 0 : struct dom_sid member_sid;
5959 0 : struct dom_sid_buf buf;
5960 0 : int rc;
5961 0 : int error = 0;
5962 :
5963 0 : switch (modop) {
5964 0 : case LDAP_MOD_ADD:
5965 0 : DEBUG(1,("ldapsam_change_groupmem: add new member(rid=%d) to a domain group(rid=%d)\n", member_rid, group_rid));
5966 0 : break;
5967 0 : case LDAP_MOD_DELETE:
5968 0 : DEBUG(1,("ldapsam_change_groupmem: delete member(rid=%d) from a domain group(rid=%d)\n", member_rid, group_rid));
5969 0 : break;
5970 0 : default:
5971 0 : return NT_STATUS_UNSUCCESSFUL;
5972 : }
5973 :
5974 : /* get member sid */
5975 0 : sid_compose(&member_sid, get_global_sam_sid(), member_rid);
5976 :
5977 : /* get the group sid */
5978 0 : sid_compose(&group_sid, get_global_sam_sid(), group_rid);
5979 :
5980 0 : filter = talloc_asprintf(tmp_ctx,
5981 : "(&(sambaSID=%s)"
5982 : "(objectClass="LDAP_OBJ_POSIXACCOUNT")"
5983 : "(objectClass="LDAP_OBJ_SAMBASAMACCOUNT"))",
5984 : dom_sid_str_buf(&member_sid, &buf));
5985 0 : if (filter == NULL) {
5986 0 : return NT_STATUS_NO_MEMORY;
5987 : }
5988 :
5989 : /* get the member uid */
5990 0 : rc = smbldap_search_suffix(ldap_state->smbldap_state, filter, NULL, &result);
5991 0 : if (rc != LDAP_SUCCESS) {
5992 0 : DEBUG(1,("ldapsam_change_groupmem: member search failed!\n"));
5993 0 : return NT_STATUS_UNSUCCESSFUL;
5994 : }
5995 0 : smbldap_talloc_autofree_ldapmsg(tmp_ctx, result);
5996 :
5997 0 : num_result = ldap_count_entries(priv2ld(ldap_state), result);
5998 :
5999 0 : if (num_result == 0) {
6000 0 : DEBUG(1,("ldapsam_change_groupmem: member not found!\n"));
6001 0 : return NT_STATUS_NO_SUCH_MEMBER;
6002 : }
6003 :
6004 0 : if (num_result > 1) {
6005 0 : DEBUG (0, ("ldapsam_change_groupmem: More than one account with the same SID ?!\n"));
6006 0 : return NT_STATUS_INTERNAL_DB_CORRUPTION;
6007 : }
6008 :
6009 0 : entry = ldap_first_entry(priv2ld(ldap_state), result);
6010 0 : if (!entry) {
6011 0 : return NT_STATUS_UNSUCCESSFUL;
6012 : }
6013 :
6014 0 : if (modop == LDAP_MOD_DELETE) {
6015 : /* check if we are trying to remove the member from his primary group */
6016 0 : char *gidstr;
6017 0 : gid_t user_gid, group_gid;
6018 :
6019 0 : gidstr = smbldap_talloc_single_attribute(priv2ld(ldap_state), entry, "gidNumber", tmp_ctx);
6020 0 : if (!gidstr) {
6021 0 : DEBUG (0, ("ldapsam_change_groupmem: Unable to find the member's gid!\n"));
6022 0 : return NT_STATUS_INTERNAL_DB_CORRUPTION;
6023 : }
6024 :
6025 0 : user_gid = smb_strtoul(gidstr, NULL, 10, &error, SMB_STR_STANDARD);
6026 0 : if (error != 0) {
6027 0 : DBG_ERR("Failed to convert user gid\n");
6028 0 : return NT_STATUS_UNSUCCESSFUL;
6029 : }
6030 :
6031 0 : if (!sid_to_gid(&group_sid, &group_gid)) {
6032 0 : DEBUG (0, ("ldapsam_change_groupmem: Unable to get group gid from SID!\n"));
6033 0 : return NT_STATUS_UNSUCCESSFUL;
6034 : }
6035 :
6036 0 : if (user_gid == group_gid) {
6037 0 : DEBUG (3, ("ldapsam_change_groupmem: can't remove user from its own primary group!\n"));
6038 0 : return NT_STATUS_MEMBERS_PRIMARY_GROUP;
6039 : }
6040 : }
6041 :
6042 : /* here it is, retrieve the uid for later use */
6043 0 : uidstr = smbldap_talloc_single_attribute(priv2ld(ldap_state), entry, "uid", tmp_ctx);
6044 0 : if (!uidstr) {
6045 0 : DEBUG (0, ("ldapsam_change_groupmem: Unable to find the member's name!\n"));
6046 0 : return NT_STATUS_INTERNAL_DB_CORRUPTION;
6047 : }
6048 :
6049 0 : filter = talloc_asprintf(tmp_ctx,
6050 : "(&(sambaSID=%s)"
6051 : "(objectClass="LDAP_OBJ_POSIXGROUP")"
6052 : "(objectClass="LDAP_OBJ_GROUPMAP"))",
6053 : dom_sid_str_buf(&group_sid, &buf));
6054 :
6055 : /* get the group */
6056 0 : rc = smbldap_search_suffix(ldap_state->smbldap_state, filter, NULL, &result);
6057 0 : if (rc != LDAP_SUCCESS) {
6058 0 : DEBUG(1,("ldapsam_change_groupmem: group search failed!\n"));
6059 0 : return NT_STATUS_UNSUCCESSFUL;
6060 : }
6061 0 : smbldap_talloc_autofree_ldapmsg(tmp_ctx, result);
6062 :
6063 0 : num_result = ldap_count_entries(priv2ld(ldap_state), result);
6064 :
6065 0 : if (num_result == 0) {
6066 0 : DEBUG(1,("ldapsam_change_groupmem: group not found!\n"));
6067 0 : return NT_STATUS_NO_SUCH_GROUP;
6068 : }
6069 :
6070 0 : if (num_result > 1) {
6071 0 : DEBUG (0, ("ldapsam_change_groupmem: More than one group with the same SID ?!\n"));
6072 0 : return NT_STATUS_INTERNAL_DB_CORRUPTION;
6073 : }
6074 :
6075 0 : entry = ldap_first_entry(priv2ld(ldap_state), result);
6076 0 : if (!entry) {
6077 0 : return NT_STATUS_UNSUCCESSFUL;
6078 : }
6079 :
6080 : /* here it is, retrieve the dn for later use */
6081 0 : dn = smbldap_talloc_dn(tmp_ctx, priv2ld(ldap_state), entry);
6082 0 : if (!dn) {
6083 0 : DEBUG(0,("ldapsam_change_groupmem: Out of memory!\n"));
6084 0 : return NT_STATUS_NO_MEMORY;
6085 : }
6086 :
6087 0 : smbldap_set_mod(&mods, modop, "memberUid", uidstr);
6088 :
6089 0 : smbldap_talloc_autofree_ldapmod(tmp_ctx, mods);
6090 :
6091 0 : rc = smbldap_modify(ldap_state->smbldap_state, dn, mods);
6092 0 : if (rc != LDAP_SUCCESS) {
6093 0 : if (rc == LDAP_TYPE_OR_VALUE_EXISTS && modop == LDAP_MOD_ADD) {
6094 0 : DEBUG(1,("ldapsam_change_groupmem: member is already in group, add failed!\n"));
6095 0 : return NT_STATUS_MEMBER_IN_GROUP;
6096 : }
6097 0 : if (rc == LDAP_NO_SUCH_ATTRIBUTE && modop == LDAP_MOD_DELETE) {
6098 0 : DEBUG(1,("ldapsam_change_groupmem: member is not in group, delete failed!\n"));
6099 0 : return NT_STATUS_MEMBER_NOT_IN_GROUP;
6100 : }
6101 0 : return NT_STATUS_UNSUCCESSFUL;
6102 : }
6103 :
6104 0 : return NT_STATUS_OK;
6105 : }
6106 :
6107 0 : static NTSTATUS ldapsam_add_groupmem(struct pdb_methods *my_methods,
6108 : TALLOC_CTX *tmp_ctx,
6109 : uint32_t group_rid,
6110 : uint32_t member_rid)
6111 : {
6112 0 : return ldapsam_change_groupmem(my_methods, tmp_ctx, group_rid, member_rid, LDAP_MOD_ADD);
6113 : }
6114 0 : static NTSTATUS ldapsam_del_groupmem(struct pdb_methods *my_methods,
6115 : TALLOC_CTX *tmp_ctx,
6116 : uint32_t group_rid,
6117 : uint32_t member_rid)
6118 : {
6119 0 : return ldapsam_change_groupmem(my_methods, tmp_ctx, group_rid, member_rid, LDAP_MOD_DELETE);
6120 : }
6121 :
6122 0 : static NTSTATUS ldapsam_set_primary_group(struct pdb_methods *my_methods,
6123 : TALLOC_CTX *mem_ctx,
6124 : struct samu *sampass)
6125 : {
6126 0 : struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
6127 0 : LDAPMessage *entry = NULL;
6128 0 : LDAPMessage *result = NULL;
6129 0 : uint32_t num_result;
6130 0 : LDAPMod **mods = NULL;
6131 0 : char *filter;
6132 0 : char *escape_username;
6133 0 : char *gidstr;
6134 0 : char *dn = NULL;
6135 0 : gid_t gid;
6136 0 : int rc;
6137 :
6138 0 : DEBUG(0,("ldapsam_set_primary_group: Attempt to set primary group for user [%s]\n", pdb_get_username(sampass)));
6139 :
6140 0 : if (!sid_to_gid(pdb_get_group_sid(sampass), &gid)) {
6141 0 : DEBUG(0,("ldapsam_set_primary_group: failed to retrieve gid from user's group SID!\n"));
6142 0 : return NT_STATUS_UNSUCCESSFUL;
6143 : }
6144 0 : gidstr = talloc_asprintf(mem_ctx, "%u", (unsigned int)gid);
6145 0 : if (!gidstr) {
6146 0 : DEBUG(0,("ldapsam_set_primary_group: Out of Memory!\n"));
6147 0 : return NT_STATUS_NO_MEMORY;
6148 : }
6149 :
6150 0 : escape_username = escape_ldap_string(talloc_tos(),
6151 : pdb_get_username(sampass));
6152 0 : if (escape_username== NULL) {
6153 0 : return NT_STATUS_NO_MEMORY;
6154 : }
6155 :
6156 0 : filter = talloc_asprintf(mem_ctx,
6157 : "(&(uid=%s)"
6158 : "(objectClass="LDAP_OBJ_POSIXACCOUNT")"
6159 : "(objectClass="LDAP_OBJ_SAMBASAMACCOUNT"))",
6160 : escape_username);
6161 :
6162 0 : TALLOC_FREE(escape_username);
6163 :
6164 0 : if (filter == NULL) {
6165 0 : return NT_STATUS_NO_MEMORY;
6166 : }
6167 :
6168 0 : rc = smbldap_search_suffix(ldap_state->smbldap_state, filter, NULL, &result);
6169 0 : if (rc != LDAP_SUCCESS) {
6170 0 : DEBUG(0,("ldapsam_set_primary_group: user search failed!\n"));
6171 0 : return NT_STATUS_UNSUCCESSFUL;
6172 : }
6173 0 : smbldap_talloc_autofree_ldapmsg(mem_ctx, result);
6174 :
6175 0 : num_result = ldap_count_entries(priv2ld(ldap_state), result);
6176 :
6177 0 : if (num_result == 0) {
6178 0 : DEBUG(0,("ldapsam_set_primary_group: user not found!\n"));
6179 0 : return NT_STATUS_NO_SUCH_USER;
6180 : }
6181 :
6182 0 : if (num_result > 1) {
6183 0 : DEBUG (0, ("ldapsam_set_primary_group: More than one user with name [%s] ?!\n", pdb_get_username(sampass)));
6184 0 : return NT_STATUS_INTERNAL_DB_CORRUPTION;
6185 : }
6186 :
6187 0 : entry = ldap_first_entry(priv2ld(ldap_state), result);
6188 0 : if (!entry) {
6189 0 : return NT_STATUS_UNSUCCESSFUL;
6190 : }
6191 :
6192 : /* retrieve the dn for later use */
6193 0 : dn = smbldap_talloc_dn(mem_ctx, priv2ld(ldap_state), entry);
6194 0 : if (!dn) {
6195 0 : DEBUG(0,("ldapsam_set_primary_group: Out of memory!\n"));
6196 0 : return NT_STATUS_NO_MEMORY;
6197 : }
6198 :
6199 : /* remove the old one, and add the new one, this way we do not risk races */
6200 0 : smbldap_make_mod(priv2ld(ldap_state), entry, &mods, "gidNumber", gidstr);
6201 :
6202 0 : if (mods == NULL) {
6203 0 : TALLOC_FREE(dn);
6204 0 : return NT_STATUS_OK;
6205 : }
6206 :
6207 0 : rc = smbldap_modify(ldap_state->smbldap_state, dn, mods);
6208 0 : TALLOC_FREE(dn);
6209 0 : if (rc != LDAP_SUCCESS) {
6210 0 : DEBUG(0,("ldapsam_set_primary_group: failed to modify [%s] primary group to [%s]\n",
6211 : pdb_get_username(sampass), gidstr));
6212 0 : return NT_STATUS_UNSUCCESSFUL;
6213 : }
6214 :
6215 0 : flush_pwnam_cache();
6216 :
6217 0 : return NT_STATUS_OK;
6218 : }
6219 :
6220 :
6221 : /**********************************************************************
6222 : trusted domains functions
6223 : *********************************************************************/
6224 :
6225 0 : static char *trusteddom_dn(struct ldapsam_privates *ldap_state,
6226 : const char *domain)
6227 : {
6228 0 : return talloc_asprintf(talloc_tos(), "sambaDomainName=%s,%s", domain,
6229 : ldap_state->domain_dn);
6230 : }
6231 :
6232 0 : static bool get_trusteddom_pw_int(struct ldapsam_privates *ldap_state,
6233 : TALLOC_CTX *mem_ctx,
6234 : const char *domain, LDAPMessage **entry)
6235 : {
6236 0 : int rc;
6237 0 : char *filter;
6238 0 : int scope = LDAP_SCOPE_SUBTREE;
6239 0 : const char **attrs = NULL; /* NULL: get all attrs */
6240 0 : int attrsonly = 0; /* 0: return values too */
6241 0 : LDAPMessage *result = NULL;
6242 0 : char *trusted_dn;
6243 0 : uint32_t num_result;
6244 :
6245 0 : filter = talloc_asprintf(talloc_tos(),
6246 : "(&(objectClass="LDAP_OBJ_TRUSTDOM_PASSWORD")(sambaDomainName=%s))",
6247 : domain);
6248 :
6249 0 : trusted_dn = trusteddom_dn(ldap_state, domain);
6250 0 : if (trusted_dn == NULL) {
6251 0 : return False;
6252 : }
6253 0 : rc = smbldap_search(ldap_state->smbldap_state, trusted_dn, scope,
6254 : filter, attrs, attrsonly, &result);
6255 :
6256 0 : if (result != NULL) {
6257 0 : smbldap_talloc_autofree_ldapmsg(mem_ctx, result);
6258 : }
6259 :
6260 0 : if (rc == LDAP_NO_SUCH_OBJECT) {
6261 0 : *entry = NULL;
6262 0 : return True;
6263 : }
6264 :
6265 0 : if (rc != LDAP_SUCCESS) {
6266 0 : return False;
6267 : }
6268 :
6269 0 : num_result = ldap_count_entries(priv2ld(ldap_state), result);
6270 :
6271 0 : if (num_result > 1) {
6272 0 : DEBUG(1, ("ldapsam_get_trusteddom_pw: more than one "
6273 : "%s object for domain '%s'?!\n",
6274 : LDAP_OBJ_TRUSTDOM_PASSWORD, domain));
6275 0 : return False;
6276 : }
6277 :
6278 0 : if (num_result == 0) {
6279 0 : DEBUG(1, ("ldapsam_get_trusteddom_pw: no "
6280 : "%s object for domain %s.\n",
6281 : LDAP_OBJ_TRUSTDOM_PASSWORD, domain));
6282 0 : *entry = NULL;
6283 : } else {
6284 0 : *entry = ldap_first_entry(priv2ld(ldap_state), result);
6285 : }
6286 :
6287 0 : return True;
6288 : }
6289 :
6290 0 : static bool ldapsam_get_trusteddom_pw(struct pdb_methods *methods,
6291 : const char *domain,
6292 : char** pwd,
6293 : struct dom_sid *sid,
6294 : time_t *pass_last_set_time)
6295 : {
6296 0 : struct ldapsam_privates *ldap_state =
6297 : (struct ldapsam_privates *)methods->private_data;
6298 0 : LDAPMessage *entry = NULL;
6299 :
6300 0 : DEBUG(10, ("ldapsam_get_trusteddom_pw called for domain %s\n", domain));
6301 :
6302 0 : if (!get_trusteddom_pw_int(ldap_state, talloc_tos(), domain, &entry) ||
6303 0 : (entry == NULL))
6304 : {
6305 0 : return False;
6306 : }
6307 :
6308 : /* password */
6309 0 : if (pwd != NULL) {
6310 0 : char *pwd_str;
6311 0 : pwd_str = smbldap_talloc_single_attribute(priv2ld(ldap_state),
6312 : entry, "sambaClearTextPassword", talloc_tos());
6313 0 : if (pwd_str == NULL) {
6314 0 : return False;
6315 : }
6316 : /* trusteddom_pw routines do not use talloc yet... */
6317 0 : *pwd = SMB_STRDUP(pwd_str);
6318 0 : if (*pwd == NULL) {
6319 0 : return False;
6320 : }
6321 : }
6322 :
6323 : /* last change time */
6324 0 : if (pass_last_set_time != NULL) {
6325 0 : char *time_str;
6326 0 : time_str = smbldap_talloc_single_attribute(priv2ld(ldap_state),
6327 : entry, "sambaPwdLastSet", talloc_tos());
6328 0 : if (time_str == NULL) {
6329 0 : return False;
6330 : }
6331 0 : *pass_last_set_time = (time_t)atol(time_str);
6332 : }
6333 :
6334 : /* domain sid */
6335 0 : if (sid != NULL) {
6336 0 : char *sid_str;
6337 0 : struct dom_sid dom_sid;
6338 0 : sid_str = smbldap_talloc_single_attribute(priv2ld(ldap_state),
6339 : entry, "sambaSID",
6340 : talloc_tos());
6341 0 : if (sid_str == NULL) {
6342 0 : return False;
6343 : }
6344 0 : if (!string_to_sid(&dom_sid, sid_str)) {
6345 0 : return False;
6346 : }
6347 0 : sid_copy(sid, &dom_sid);
6348 : }
6349 :
6350 0 : return True;
6351 : }
6352 :
6353 0 : static bool ldapsam_set_trusteddom_pw(struct pdb_methods *methods,
6354 : const char* domain,
6355 : const char* pwd,
6356 : const struct dom_sid *sid)
6357 : {
6358 0 : struct ldapsam_privates *ldap_state =
6359 : (struct ldapsam_privates *)methods->private_data;
6360 0 : LDAPMessage *entry = NULL;
6361 0 : LDAPMod **mods = NULL;
6362 0 : char *prev_pwd = NULL;
6363 0 : char *trusted_dn = NULL;
6364 0 : struct dom_sid_buf buf;
6365 0 : int rc;
6366 :
6367 0 : DEBUG(10, ("ldapsam_set_trusteddom_pw called for domain %s\n", domain));
6368 :
6369 : /*
6370 : * get the current entry (if there is one) in order to put the
6371 : * current password into the previous password attribute
6372 : */
6373 0 : if (!get_trusteddom_pw_int(ldap_state, talloc_tos(), domain, &entry)) {
6374 0 : return False;
6375 : }
6376 :
6377 0 : mods = NULL;
6378 0 : smbldap_make_mod(priv2ld(ldap_state), entry, &mods, "objectClass",
6379 : LDAP_OBJ_TRUSTDOM_PASSWORD);
6380 0 : smbldap_make_mod(priv2ld(ldap_state), entry, &mods, "sambaDomainName",
6381 : domain);
6382 0 : smbldap_make_mod(priv2ld(ldap_state), entry, &mods, "sambaSID",
6383 0 : dom_sid_str_buf(sid, &buf));
6384 0 : smbldap_make_mod(priv2ld(ldap_state), entry, &mods, "sambaPwdLastSet",
6385 0 : talloc_asprintf(talloc_tos(), "%li", (long int)time(NULL)));
6386 0 : smbldap_make_mod(priv2ld(ldap_state), entry, &mods,
6387 : "sambaClearTextPassword", pwd);
6388 :
6389 0 : if (entry != NULL) {
6390 0 : prev_pwd = smbldap_talloc_single_attribute(priv2ld(ldap_state),
6391 : entry, "sambaClearTextPassword", talloc_tos());
6392 0 : if (prev_pwd != NULL) {
6393 0 : smbldap_make_mod(priv2ld(ldap_state), entry, &mods,
6394 : "sambaPreviousClearTextPassword",
6395 : prev_pwd);
6396 : }
6397 : }
6398 :
6399 0 : smbldap_talloc_autofree_ldapmod(talloc_tos(), mods);
6400 :
6401 0 : trusted_dn = trusteddom_dn(ldap_state, domain);
6402 0 : if (trusted_dn == NULL) {
6403 0 : return False;
6404 : }
6405 0 : if (entry == NULL) {
6406 0 : rc = smbldap_add(ldap_state->smbldap_state, trusted_dn, mods);
6407 : } else {
6408 0 : rc = smbldap_modify(ldap_state->smbldap_state, trusted_dn, mods);
6409 : }
6410 :
6411 0 : if (rc != LDAP_SUCCESS) {
6412 0 : DEBUG(1, ("error writing trusted domain password!\n"));
6413 0 : return False;
6414 : }
6415 :
6416 0 : return True;
6417 : }
6418 :
6419 0 : static bool ldapsam_del_trusteddom_pw(struct pdb_methods *methods,
6420 : const char *domain)
6421 : {
6422 0 : int rc;
6423 0 : struct ldapsam_privates *ldap_state =
6424 : (struct ldapsam_privates *)methods->private_data;
6425 0 : LDAPMessage *entry = NULL;
6426 0 : const char *trusted_dn;
6427 :
6428 0 : if (!get_trusteddom_pw_int(ldap_state, talloc_tos(), domain, &entry)) {
6429 0 : return False;
6430 : }
6431 :
6432 0 : if (entry == NULL) {
6433 0 : DEBUG(5, ("ldapsam_del_trusteddom_pw: no such trusted domain: "
6434 : "%s\n", domain));
6435 0 : return True;
6436 : }
6437 :
6438 0 : trusted_dn = smbldap_talloc_dn(talloc_tos(), priv2ld(ldap_state),
6439 : entry);
6440 0 : if (trusted_dn == NULL) {
6441 0 : DEBUG(0,("ldapsam_del_trusteddom_pw: Out of memory!\n"));
6442 0 : return False;
6443 : }
6444 :
6445 0 : rc = smbldap_delete(ldap_state->smbldap_state, trusted_dn);
6446 0 : if (rc != LDAP_SUCCESS) {
6447 0 : return False;
6448 : }
6449 :
6450 0 : return True;
6451 : }
6452 :
6453 0 : static NTSTATUS ldapsam_enum_trusteddoms(struct pdb_methods *methods,
6454 : TALLOC_CTX *mem_ctx,
6455 : uint32_t *num_domains,
6456 : struct trustdom_info ***domains)
6457 : {
6458 0 : int rc;
6459 0 : struct ldapsam_privates *ldap_state =
6460 : (struct ldapsam_privates *)methods->private_data;
6461 0 : const char *filter;
6462 0 : int scope = LDAP_SCOPE_SUBTREE;
6463 0 : const char *attrs[] = { "sambaDomainName", "sambaSID", NULL };
6464 0 : int attrsonly = 0; /* 0: return values too */
6465 0 : LDAPMessage *result = NULL;
6466 0 : LDAPMessage *entry = NULL;
6467 :
6468 0 : filter = "(objectClass="LDAP_OBJ_TRUSTDOM_PASSWORD")";
6469 :
6470 0 : rc = smbldap_search(ldap_state->smbldap_state,
6471 0 : ldap_state->domain_dn,
6472 : scope,
6473 : filter,
6474 : attrs,
6475 : attrsonly,
6476 : &result);
6477 :
6478 0 : if (result != NULL) {
6479 0 : smbldap_talloc_autofree_ldapmsg(mem_ctx, result);
6480 : }
6481 :
6482 0 : if (rc != LDAP_SUCCESS) {
6483 0 : return NT_STATUS_UNSUCCESSFUL;
6484 : }
6485 :
6486 0 : *num_domains = 0;
6487 0 : if (!(*domains = talloc_array(mem_ctx, struct trustdom_info *, 1))) {
6488 0 : DEBUG(1, ("talloc failed\n"));
6489 0 : return NT_STATUS_NO_MEMORY;
6490 : }
6491 :
6492 0 : for (entry = ldap_first_entry(priv2ld(ldap_state), result);
6493 0 : entry != NULL;
6494 0 : entry = ldap_next_entry(priv2ld(ldap_state), entry))
6495 : {
6496 0 : char *dom_name, *dom_sid_str;
6497 0 : struct trustdom_info *dom_info;
6498 :
6499 0 : dom_info = talloc(*domains, struct trustdom_info);
6500 0 : if (dom_info == NULL) {
6501 0 : DEBUG(1, ("talloc failed\n"));
6502 0 : return NT_STATUS_NO_MEMORY;
6503 : }
6504 :
6505 0 : dom_name = smbldap_talloc_single_attribute(priv2ld(ldap_state),
6506 : entry,
6507 : "sambaDomainName",
6508 : talloc_tos());
6509 0 : if (dom_name == NULL) {
6510 0 : DEBUG(1, ("talloc failed\n"));
6511 0 : return NT_STATUS_NO_MEMORY;
6512 : }
6513 0 : dom_info->name = dom_name;
6514 :
6515 0 : dom_sid_str = smbldap_talloc_single_attribute(
6516 : priv2ld(ldap_state), entry, "sambaSID",
6517 : talloc_tos());
6518 0 : if (dom_sid_str == NULL) {
6519 0 : DEBUG(1, ("talloc failed\n"));
6520 0 : return NT_STATUS_NO_MEMORY;
6521 : }
6522 0 : if (!string_to_sid(&dom_info->sid, dom_sid_str)) {
6523 0 : DEBUG(1, ("Error calling string_to_sid on SID %s\n",
6524 : dom_sid_str));
6525 0 : return NT_STATUS_UNSUCCESSFUL;
6526 : }
6527 :
6528 0 : ADD_TO_ARRAY(*domains, struct trustdom_info *, dom_info,
6529 : domains, num_domains);
6530 :
6531 0 : if (*domains == NULL) {
6532 0 : DEBUG(1, ("talloc failed\n"));
6533 0 : return NT_STATUS_NO_MEMORY;
6534 : }
6535 : }
6536 :
6537 0 : DEBUG(5, ("ldapsam_enum_trusteddoms: got %d domains\n", *num_domains));
6538 0 : return NT_STATUS_OK;
6539 : }
6540 :
6541 :
6542 : /**********************************************************************
6543 : Housekeeping
6544 : *********************************************************************/
6545 :
6546 0 : static void free_private_data(void **vp)
6547 : {
6548 0 : struct ldapsam_privates **ldap_state = (struct ldapsam_privates **)vp;
6549 :
6550 0 : smbldap_free_struct(&(*ldap_state)->smbldap_state);
6551 :
6552 0 : if ((*ldap_state)->result != NULL) {
6553 0 : ldap_msgfree((*ldap_state)->result);
6554 0 : (*ldap_state)->result = NULL;
6555 : }
6556 0 : if ((*ldap_state)->domain_dn != NULL) {
6557 0 : SAFE_FREE((*ldap_state)->domain_dn);
6558 : }
6559 :
6560 0 : *ldap_state = NULL;
6561 :
6562 : /* No need to free any further, as it is talloc()ed */
6563 0 : }
6564 :
6565 : /*********************************************************************
6566 : Initialise the parts of the pdb_methods structure that are common to
6567 : all pdb_ldap modes
6568 : *********************************************************************/
6569 :
6570 0 : static NTSTATUS pdb_init_ldapsam_common(struct pdb_methods **pdb_method, const char *location)
6571 : {
6572 0 : NTSTATUS nt_status;
6573 0 : struct ldapsam_privates *ldap_state;
6574 0 : char *bind_dn = NULL;
6575 0 : char *bind_secret = NULL;
6576 :
6577 0 : if (!NT_STATUS_IS_OK(nt_status = make_pdb_method( pdb_method ))) {
6578 0 : return nt_status;
6579 : }
6580 :
6581 0 : (*pdb_method)->name = "ldapsam";
6582 :
6583 0 : (*pdb_method)->getsampwnam = ldapsam_getsampwnam;
6584 0 : (*pdb_method)->getsampwsid = ldapsam_getsampwsid;
6585 0 : (*pdb_method)->add_sam_account = ldapsam_add_sam_account;
6586 0 : (*pdb_method)->update_sam_account = ldapsam_update_sam_account;
6587 0 : (*pdb_method)->delete_sam_account = ldapsam_delete_sam_account;
6588 0 : (*pdb_method)->rename_sam_account = ldapsam_rename_sam_account;
6589 :
6590 0 : (*pdb_method)->getgrsid = ldapsam_getgrsid;
6591 0 : (*pdb_method)->getgrgid = ldapsam_getgrgid;
6592 0 : (*pdb_method)->getgrnam = ldapsam_getgrnam;
6593 0 : (*pdb_method)->add_group_mapping_entry = ldapsam_add_group_mapping_entry;
6594 0 : (*pdb_method)->update_group_mapping_entry = ldapsam_update_group_mapping_entry;
6595 0 : (*pdb_method)->delete_group_mapping_entry = ldapsam_delete_group_mapping_entry;
6596 0 : (*pdb_method)->enum_group_mapping = ldapsam_enum_group_mapping;
6597 :
6598 0 : (*pdb_method)->get_account_policy = ldapsam_get_account_policy;
6599 0 : (*pdb_method)->set_account_policy = ldapsam_set_account_policy;
6600 :
6601 0 : (*pdb_method)->get_seq_num = ldapsam_get_seq_num;
6602 :
6603 0 : (*pdb_method)->capabilities = ldapsam_capabilities;
6604 0 : (*pdb_method)->new_rid = ldapsam_new_rid;
6605 :
6606 0 : (*pdb_method)->get_trusteddom_pw = ldapsam_get_trusteddom_pw;
6607 0 : (*pdb_method)->set_trusteddom_pw = ldapsam_set_trusteddom_pw;
6608 0 : (*pdb_method)->del_trusteddom_pw = ldapsam_del_trusteddom_pw;
6609 0 : (*pdb_method)->enum_trusteddoms = ldapsam_enum_trusteddoms;
6610 :
6611 : /* TODO: Setup private data and free */
6612 :
6613 0 : if ( !(ldap_state = talloc_zero(*pdb_method, struct ldapsam_privates)) ) {
6614 0 : DEBUG(0, ("pdb_init_ldapsam_common: talloc() failed for ldapsam private_data!\n"));
6615 0 : return NT_STATUS_NO_MEMORY;
6616 : }
6617 :
6618 0 : if (!fetch_ldap_pw(&bind_dn, &bind_secret)) {
6619 0 : DEBUG(0, ("pdb_init_ldapsam_common: Failed to retrieve LDAP password from secrets.tdb\n"));
6620 0 : return NT_STATUS_NO_MEMORY;
6621 : }
6622 :
6623 0 : nt_status = smbldap_init(*pdb_method, pdb_get_tevent_context(),
6624 : location, false, bind_dn, bind_secret,
6625 : &ldap_state->smbldap_state);
6626 0 : BURN_FREE_STR(bind_secret);
6627 0 : SAFE_FREE(bind_dn);
6628 0 : if ( !NT_STATUS_IS_OK(nt_status) ) {
6629 0 : return nt_status;
6630 : }
6631 :
6632 0 : if ( !(ldap_state->domain_name = talloc_strdup(*pdb_method, get_global_sam_name()) ) ) {
6633 0 : return NT_STATUS_NO_MEMORY;
6634 : }
6635 :
6636 0 : (*pdb_method)->private_data = ldap_state;
6637 :
6638 0 : (*pdb_method)->free_private_data = free_private_data;
6639 :
6640 0 : return NT_STATUS_OK;
6641 : }
6642 :
6643 0 : static bool ldapsam_is_responsible_for_wellknown(struct pdb_methods *m)
6644 : {
6645 0 : return true;
6646 : }
6647 :
6648 : /**********************************************************************
6649 : Initialise the normal mode for pdb_ldap
6650 : *********************************************************************/
6651 :
6652 0 : NTSTATUS pdb_ldapsam_init_common(struct pdb_methods **pdb_method,
6653 : const char *location)
6654 : {
6655 0 : NTSTATUS nt_status;
6656 0 : struct ldapsam_privates *ldap_state = NULL;
6657 0 : uint32_t alg_rid_base;
6658 0 : char *alg_rid_base_string = NULL;
6659 0 : LDAPMessage *result = NULL;
6660 0 : LDAPMessage *entry = NULL;
6661 0 : struct dom_sid ldap_domain_sid;
6662 0 : struct dom_sid secrets_domain_sid;
6663 0 : char *domain_sid_string = NULL;
6664 0 : char *dn = NULL;
6665 0 : char *uri = talloc_strdup( NULL, location );
6666 :
6667 0 : trim_char( uri, '\"', '\"' );
6668 0 : nt_status = pdb_init_ldapsam_common(pdb_method, uri);
6669 :
6670 0 : TALLOC_FREE(uri);
6671 :
6672 0 : if (!NT_STATUS_IS_OK(nt_status)) {
6673 0 : return nt_status;
6674 : }
6675 :
6676 0 : (*pdb_method)->name = "ldapsam";
6677 :
6678 0 : (*pdb_method)->add_aliasmem = ldapsam_add_aliasmem;
6679 0 : (*pdb_method)->del_aliasmem = ldapsam_del_aliasmem;
6680 0 : (*pdb_method)->enum_aliasmem = ldapsam_enum_aliasmem;
6681 0 : (*pdb_method)->enum_alias_memberships = ldapsam_alias_memberships;
6682 0 : (*pdb_method)->search_users = ldapsam_search_users;
6683 0 : (*pdb_method)->search_groups = ldapsam_search_groups;
6684 0 : (*pdb_method)->search_aliases = ldapsam_search_aliases;
6685 0 : (*pdb_method)->is_responsible_for_wellknown =
6686 : ldapsam_is_responsible_for_wellknown;
6687 :
6688 0 : if (lp_parm_bool(-1, "ldapsam", "trusted", False)) {
6689 0 : (*pdb_method)->enum_group_members = ldapsam_enum_group_members;
6690 0 : (*pdb_method)->enum_group_memberships =
6691 : ldapsam_enum_group_memberships;
6692 0 : (*pdb_method)->lookup_rids = ldapsam_lookup_rids;
6693 0 : (*pdb_method)->sid_to_id = ldapsam_sid_to_id;
6694 0 : (*pdb_method)->id_to_sid = ldapsam_id_to_sid;
6695 :
6696 0 : if (lp_parm_bool(-1, "ldapsam", "editposix", False)) {
6697 0 : (*pdb_method)->create_user = ldapsam_create_user;
6698 0 : (*pdb_method)->delete_user = ldapsam_delete_user;
6699 0 : (*pdb_method)->create_dom_group = ldapsam_create_dom_group;
6700 0 : (*pdb_method)->delete_dom_group = ldapsam_delete_dom_group;
6701 0 : (*pdb_method)->add_groupmem = ldapsam_add_groupmem;
6702 0 : (*pdb_method)->del_groupmem = ldapsam_del_groupmem;
6703 0 : (*pdb_method)->set_unix_primary_group = ldapsam_set_primary_group;
6704 : }
6705 : }
6706 :
6707 0 : ldap_state = (struct ldapsam_privates *)((*pdb_method)->private_data);
6708 0 : ldap_state->schema_ver = SCHEMAVER_SAMBASAMACCOUNT;
6709 :
6710 : /* Try to setup the Domain Name, Domain SID, algorithmic rid base */
6711 :
6712 0 : nt_status = smbldap_search_domain_info(ldap_state->smbldap_state,
6713 : &result,
6714 : ldap_state->domain_name, True);
6715 :
6716 0 : if ( !NT_STATUS_IS_OK(nt_status) ) {
6717 0 : DEBUG(0, ("pdb_init_ldapsam: WARNING: Could not get domain "
6718 : "info, nor add one to the domain. "
6719 : "We cannot work reliably without it.\n"));
6720 0 : return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
6721 : }
6722 :
6723 : /* Given that the above might fail, everything below this must be
6724 : * optional */
6725 :
6726 0 : entry = ldap_first_entry(smbldap_get_ldap(ldap_state->smbldap_state),
6727 : result);
6728 0 : if (!entry) {
6729 0 : DEBUG(0, ("pdb_init_ldapsam: Could not get domain info "
6730 : "entry\n"));
6731 0 : ldap_msgfree(result);
6732 0 : return NT_STATUS_UNSUCCESSFUL;
6733 : }
6734 :
6735 0 : dn = smbldap_talloc_dn(talloc_tos(),
6736 : smbldap_get_ldap(ldap_state->smbldap_state),
6737 : entry);
6738 0 : if (!dn) {
6739 0 : ldap_msgfree(result);
6740 0 : return NT_STATUS_UNSUCCESSFUL;
6741 : }
6742 :
6743 0 : ldap_state->domain_dn = smb_xstrdup(dn);
6744 0 : TALLOC_FREE(dn);
6745 :
6746 0 : domain_sid_string = smbldap_talloc_single_attribute(
6747 : smbldap_get_ldap(ldap_state->smbldap_state),
6748 : entry,
6749 : get_userattr_key2string(ldap_state->schema_ver,
6750 : LDAP_ATTR_USER_SID),
6751 : talloc_tos());
6752 :
6753 0 : if (domain_sid_string) {
6754 0 : bool found_sid;
6755 0 : if (!string_to_sid(&ldap_domain_sid, domain_sid_string)) {
6756 0 : DEBUG(1, ("pdb_init_ldapsam: SID [%s] could not be "
6757 : "read as a valid SID\n", domain_sid_string));
6758 0 : ldap_msgfree(result);
6759 0 : TALLOC_FREE(domain_sid_string);
6760 0 : return NT_STATUS_INVALID_PARAMETER;
6761 : }
6762 0 : found_sid = PDB_secrets_fetch_domain_sid(ldap_state->domain_name,
6763 : &secrets_domain_sid);
6764 0 : if (!found_sid || !dom_sid_equal(&secrets_domain_sid,
6765 : &ldap_domain_sid)) {
6766 0 : struct dom_sid_buf buf1, buf2;
6767 0 : DEBUG(1, ("pdb_init_ldapsam: Resetting SID for domain "
6768 : "%s based on pdb_ldap results %s -> %s\n",
6769 : ldap_state->domain_name,
6770 : dom_sid_str_buf(&secrets_domain_sid, &buf1),
6771 : dom_sid_str_buf(&ldap_domain_sid, &buf2)));
6772 :
6773 : /* reset secrets.tdb sid */
6774 0 : PDB_secrets_store_domain_sid(ldap_state->domain_name,
6775 : &ldap_domain_sid);
6776 0 : DEBUG(1, ("New global sam SID: %s\n",
6777 : dom_sid_str_buf(get_global_sam_sid(),
6778 : &buf1)));
6779 : }
6780 0 : sid_copy(&ldap_state->domain_sid, &ldap_domain_sid);
6781 0 : TALLOC_FREE(domain_sid_string);
6782 : }
6783 :
6784 0 : alg_rid_base_string = smbldap_talloc_single_attribute(
6785 : smbldap_get_ldap(ldap_state->smbldap_state),
6786 : entry,
6787 : get_attr_key2string( dominfo_attr_list,
6788 : LDAP_ATTR_ALGORITHMIC_RID_BASE ),
6789 : talloc_tos());
6790 0 : if (alg_rid_base_string) {
6791 0 : alg_rid_base = (uint32_t)atol(alg_rid_base_string);
6792 0 : if (alg_rid_base != algorithmic_rid_base()) {
6793 0 : DEBUG(0, ("The value of 'algorithmic RID base' has "
6794 : "changed since the LDAP\n"
6795 : "database was initialised. Aborting. \n"));
6796 0 : ldap_msgfree(result);
6797 0 : TALLOC_FREE(alg_rid_base_string);
6798 0 : return NT_STATUS_UNSUCCESSFUL;
6799 : }
6800 0 : TALLOC_FREE(alg_rid_base_string);
6801 : }
6802 0 : ldap_msgfree(result);
6803 :
6804 0 : return NT_STATUS_OK;
6805 : }
6806 :
6807 1661 : NTSTATUS pdb_ldapsam_init(TALLOC_CTX *ctx)
6808 : {
6809 16 : NTSTATUS nt_status;
6810 :
6811 1661 : nt_status = smb_register_passdb(PASSDB_INTERFACE_VERSION,
6812 : "ldapsam",
6813 : pdb_ldapsam_init_common);
6814 1661 : if (!NT_STATUS_IS_OK(nt_status)) {
6815 0 : return nt_status;
6816 : }
6817 :
6818 : /* Let pdb_nds register backends */
6819 1661 : pdb_nds_init(ctx);
6820 :
6821 1661 : return NT_STATUS_OK;
6822 : }
|