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 schame 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 : fstring objclass_filter;
145 : 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 : TALLOC_CTX *mem_ctx;
173 0 : char **values = NULL;
174 : int rc, num_result, num_values, rid;
175 0 : char *suffix = NULL;
176 : char *tok;
177 : const char *p;
178 : const char **attrs;
179 :
180 : /* Unfortunatly 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 : int rc;
367 : 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 : char *name;
398 : 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 : char *temp;
444 : 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 : 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 : uint32_t user_rid;
494 : uint8_t smblmpwd[LM_HASH_LEN],
495 : smbntpwd[NT_HASH_LEN];
496 0 : bool use_samba_attrs = True;
497 : uint16_t logon_divs;
498 0 : uint16_t bad_password_count = 0,
499 0 : logon_count = 0;
500 : uint32_t hours_len;
501 : uint8_t hours[MAX_HOURS_LEN];
502 0 : char *temp = NULL;
503 : struct login_cache cache_entry;
504 : 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 : char *user_dn;
787 : size_t pwd_len;
788 : 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 : 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 : struct passwd unix_pw;
981 0 : bool have_uid = false;
982 0 : bool have_gid = false;
983 : struct dom_sid mapped_gsid;
984 : const struct dom_sid *primary_gsid;
985 : 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 : 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 : 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 : 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 : 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 : 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 : 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 : 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 : 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 : 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 : ;
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 : int count;
1547 : const char ** attr_list;
1548 : 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 : 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 : int count;
1639 : 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 : 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 : 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 passord 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 : 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 : BerElement *ber;
1708 : struct berval *bv;
1709 0 : char *retoid = NULL;
1710 0 : struct berval *retdata = NULL;
1711 : char *utf8_password;
1712 : char *utf8_dn;
1713 : size_t converted_size;
1714 : 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 : const char *sname;
1879 : int rc;
1880 : LDAPMessage *msg, *entry;
1881 0 : NTSTATUS result = NT_STATUS_NO_MEMORY;
1882 : const char **attr_list;
1883 : 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 : NTSTATUS ret;
1937 0 : struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
1938 0 : int rc = 0;
1939 : char *dn;
1940 0 : LDAPMessage *result = NULL;
1941 0 : LDAPMessage *entry = NULL;
1942 0 : LDAPMod **mods = NULL;
1943 : 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 : const char *oldname;
2049 : int rc;
2050 0 : char *rename_script = NULL;
2051 : 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 : 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 : uint32_t num_result;
2134 : 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 : 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 : 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 : 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 : int rc;
2376 : 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 : 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 : 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 : NTSTATUS status;
2580 : 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 : 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 : 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 : fstring str;
2650 : 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 : 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 : LDAPMessage *entry;
2693 : char *filter;
2694 0 : char **values = NULL;
2695 : char **memberuid;
2696 : char *gidstr;
2697 : int rc, count;
2698 : 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=%s)"
2705 : "(objectClass=%s)"
2706 : "(sambaSID=%s))",
2707 : LDAP_OBJ_POSIXGROUP,
2708 : LDAP_OBJ_GROUPMAP,
2709 : dom_sid_str_buf(group, &buf));
2710 0 : if (filter == NULL) {
2711 0 : ret = NT_STATUS_NO_MEMORY;
2712 0 : goto done;
2713 : }
2714 :
2715 0 : rc = smbldap_search(conn, lp_ldap_suffix(),
2716 : LDAP_SCOPE_SUBTREE, filter, id_attrs, 0,
2717 : &result);
2718 :
2719 0 : if (rc != LDAP_SUCCESS)
2720 0 : goto done;
2721 :
2722 0 : smbldap_talloc_autofree_ldapmsg(mem_ctx, result);
2723 :
2724 0 : count = ldap_count_entries(smbldap_get_ldap(conn), result);
2725 :
2726 0 : if (count > 1) {
2727 0 : DEBUG(1, ("Found more than one groupmap entry for %s\n",
2728 : dom_sid_str_buf(group, &buf)));
2729 0 : ret = NT_STATUS_INTERNAL_DB_CORRUPTION;
2730 0 : goto done;
2731 : }
2732 :
2733 0 : if (count == 0) {
2734 0 : ret = NT_STATUS_NO_SUCH_GROUP;
2735 0 : goto done;
2736 : }
2737 :
2738 0 : entry = ldap_first_entry(smbldap_get_ldap(conn), result);
2739 0 : if (entry == NULL)
2740 0 : goto done;
2741 :
2742 0 : gidstr = smbldap_talloc_single_attribute(priv2ld(ldap_state), entry, "gidNumber", mem_ctx);
2743 0 : if (!gidstr) {
2744 0 : DEBUG (0, ("ldapsam_enum_group_members: Unable to find the group's gid!\n"));
2745 0 : ret = NT_STATUS_INTERNAL_DB_CORRUPTION;
2746 0 : goto done;
2747 : }
2748 :
2749 0 : values = ldap_get_values(smbldap_get_ldap(conn), entry, "memberUid");
2750 :
2751 0 : if ((values != NULL) && (values[0] != NULL)) {
2752 :
2753 0 : filter = talloc_asprintf(mem_ctx, "(&(objectClass=%s)(|", LDAP_OBJ_SAMBASAMACCOUNT);
2754 0 : if (filter == NULL) {
2755 0 : ret = NT_STATUS_NO_MEMORY;
2756 0 : goto done;
2757 : }
2758 :
2759 0 : for (memberuid = values; *memberuid != NULL; memberuid += 1) {
2760 : char *escape_memberuid;
2761 :
2762 0 : escape_memberuid = escape_ldap_string(talloc_tos(),
2763 : *memberuid);
2764 0 : if (escape_memberuid == NULL) {
2765 0 : ret = NT_STATUS_NO_MEMORY;
2766 0 : goto done;
2767 : }
2768 :
2769 0 : filter = talloc_asprintf_append_buffer(filter, "(uid=%s)", escape_memberuid);
2770 0 : TALLOC_FREE(escape_memberuid);
2771 0 : if (filter == NULL) {
2772 0 : ret = NT_STATUS_NO_MEMORY;
2773 0 : goto done;
2774 : }
2775 : }
2776 :
2777 0 : filter = talloc_asprintf_append_buffer(filter, "))");
2778 0 : if (filter == NULL) {
2779 0 : ret = NT_STATUS_NO_MEMORY;
2780 0 : goto done;
2781 : }
2782 :
2783 0 : rc = smbldap_search(conn, lp_ldap_suffix(),
2784 : LDAP_SCOPE_SUBTREE, filter, sid_attrs, 0,
2785 : &result);
2786 :
2787 0 : if (rc != LDAP_SUCCESS)
2788 0 : goto done;
2789 :
2790 0 : count = ldap_count_entries(smbldap_get_ldap(conn), result);
2791 0 : DEBUG(10,("ldapsam_enum_group_members: found %d accounts\n", count));
2792 :
2793 0 : smbldap_talloc_autofree_ldapmsg(mem_ctx, result);
2794 :
2795 0 : for (entry = ldap_first_entry(smbldap_get_ldap(conn), result);
2796 0 : entry != NULL;
2797 0 : entry = ldap_next_entry(smbldap_get_ldap(conn), entry))
2798 : {
2799 : char *sidstr;
2800 : struct dom_sid sid;
2801 : uint32_t rid;
2802 :
2803 0 : sidstr = smbldap_talloc_single_attribute(
2804 : smbldap_get_ldap(conn), entry, "sambaSID",
2805 : mem_ctx);
2806 0 : if (!sidstr) {
2807 0 : DEBUG(0, ("Severe DB error, %s can't miss the sambaSID"
2808 : "attribute\n", LDAP_OBJ_SAMBASAMACCOUNT));
2809 0 : ret = NT_STATUS_INTERNAL_DB_CORRUPTION;
2810 0 : goto done;
2811 : }
2812 :
2813 0 : if (!string_to_sid(&sid, sidstr))
2814 0 : goto done;
2815 :
2816 0 : if (!sid_check_is_in_our_sam(&sid)) {
2817 0 : DEBUG(0, ("Inconsistent SAM -- group member uid not "
2818 : "in our domain\n"));
2819 0 : ret = NT_STATUS_INTERNAL_DB_CORRUPTION;
2820 0 : goto done;
2821 : }
2822 :
2823 0 : sid_peek_rid(&sid, &rid);
2824 :
2825 0 : if (!add_rid_to_array_unique(mem_ctx, rid, pp_member_rids,
2826 : p_num_members)) {
2827 0 : ret = NT_STATUS_NO_MEMORY;
2828 0 : goto done;
2829 : }
2830 : }
2831 : }
2832 :
2833 0 : filter = talloc_asprintf(mem_ctx,
2834 : "(&(objectClass=%s)"
2835 : "(gidNumber=%s))",
2836 : LDAP_OBJ_SAMBASAMACCOUNT,
2837 : gidstr);
2838 :
2839 0 : rc = smbldap_search(conn, lp_ldap_suffix(),
2840 : LDAP_SCOPE_SUBTREE, filter, sid_attrs, 0,
2841 : &result);
2842 :
2843 0 : if (rc != LDAP_SUCCESS)
2844 0 : goto done;
2845 :
2846 0 : smbldap_talloc_autofree_ldapmsg(mem_ctx, result);
2847 :
2848 0 : for (entry = ldap_first_entry(smbldap_get_ldap(conn), result);
2849 0 : entry != NULL;
2850 0 : entry = ldap_next_entry(smbldap_get_ldap(conn), entry))
2851 : {
2852 : uint32_t rid;
2853 :
2854 0 : if (!ldapsam_extract_rid_from_entry(smbldap_get_ldap(conn),
2855 : entry,
2856 0 : get_global_sam_sid(),
2857 : &rid)) {
2858 0 : DEBUG(0, ("Severe DB error, %s can't miss the samba SID" "attribute\n", LDAP_OBJ_SAMBASAMACCOUNT));
2859 0 : ret = NT_STATUS_INTERNAL_DB_CORRUPTION;
2860 0 : goto done;
2861 : }
2862 :
2863 0 : if (!add_rid_to_array_unique(mem_ctx, rid, pp_member_rids,
2864 : p_num_members)) {
2865 0 : ret = NT_STATUS_NO_MEMORY;
2866 0 : goto done;
2867 : }
2868 : }
2869 :
2870 0 : ret = NT_STATUS_OK;
2871 :
2872 0 : done:
2873 :
2874 0 : if (values)
2875 0 : ldap_value_free(values);
2876 :
2877 0 : return ret;
2878 : }
2879 :
2880 0 : static NTSTATUS ldapsam_enum_group_memberships(struct pdb_methods *methods,
2881 : TALLOC_CTX *mem_ctx,
2882 : struct samu *user,
2883 : struct dom_sid **pp_sids,
2884 : gid_t **pp_gids,
2885 : uint32_t *p_num_groups)
2886 : {
2887 0 : struct ldapsam_privates *ldap_state =
2888 : (struct ldapsam_privates *)methods->private_data;
2889 0 : struct smbldap_state *conn = ldap_state->smbldap_state;
2890 : char *filter;
2891 0 : const char *attrs[] = { "gidNumber", "sambaSID", NULL };
2892 : char *escape_name;
2893 : int rc, count;
2894 0 : LDAPMessage *result = NULL;
2895 : LDAPMessage *entry;
2896 0 : NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
2897 : uint32_t num_sids;
2898 : uint32_t num_gids;
2899 : char *gidstr;
2900 0 : gid_t primary_gid = -1;
2901 0 : int error = 0;
2902 :
2903 0 : *pp_sids = NULL;
2904 0 : num_sids = 0;
2905 :
2906 0 : if (pdb_get_username(user) == NULL) {
2907 0 : return NT_STATUS_INVALID_PARAMETER;
2908 : }
2909 :
2910 0 : escape_name = escape_ldap_string(talloc_tos(), pdb_get_username(user));
2911 0 : if (escape_name == NULL)
2912 0 : return NT_STATUS_NO_MEMORY;
2913 :
2914 0 : if (user->unix_pw) {
2915 0 : primary_gid = user->unix_pw->pw_gid;
2916 : } else {
2917 : /* retrieve the users primary gid */
2918 0 : filter = talloc_asprintf(mem_ctx,
2919 : "(&(objectClass=%s)(uid=%s))",
2920 : LDAP_OBJ_SAMBASAMACCOUNT,
2921 : escape_name);
2922 0 : if (filter == NULL) {
2923 0 : ret = NT_STATUS_NO_MEMORY;
2924 0 : goto done;
2925 : }
2926 :
2927 0 : rc = smbldap_search(conn, lp_ldap_suffix(),
2928 : LDAP_SCOPE_SUBTREE, filter, attrs, 0, &result);
2929 :
2930 0 : if (rc != LDAP_SUCCESS)
2931 0 : goto done;
2932 :
2933 0 : smbldap_talloc_autofree_ldapmsg(mem_ctx, result);
2934 :
2935 0 : count = ldap_count_entries(priv2ld(ldap_state), result);
2936 :
2937 0 : switch (count) {
2938 0 : case 0:
2939 0 : DEBUG(1, ("User account [%s] not found!\n", pdb_get_username(user)));
2940 0 : ret = NT_STATUS_NO_SUCH_USER;
2941 0 : goto done;
2942 0 : case 1:
2943 0 : entry = ldap_first_entry(priv2ld(ldap_state), result);
2944 :
2945 0 : gidstr = smbldap_talloc_single_attribute(priv2ld(ldap_state), entry, "gidNumber", mem_ctx);
2946 0 : if (!gidstr) {
2947 0 : DEBUG (1, ("Unable to find the member's gid!\n"));
2948 0 : ret = NT_STATUS_INTERNAL_DB_CORRUPTION;
2949 0 : goto done;
2950 : }
2951 0 : primary_gid = smb_strtoul(gidstr,
2952 : NULL,
2953 : 10,
2954 : &error,
2955 : SMB_STR_STANDARD);
2956 0 : if (error != 0) {
2957 0 : DBG_ERR("Failed to convert GID\n");
2958 0 : goto done;
2959 : }
2960 0 : break;
2961 0 : default:
2962 0 : DEBUG(1, ("found more than one account with the same user name ?!\n"));
2963 0 : ret = NT_STATUS_INTERNAL_DB_CORRUPTION;
2964 0 : goto done;
2965 : }
2966 : }
2967 :
2968 0 : filter = talloc_asprintf(mem_ctx,
2969 : "(&(objectClass=%s)(|(memberUid=%s)(gidNumber=%u)))",
2970 : LDAP_OBJ_POSIXGROUP, escape_name, (unsigned int)primary_gid);
2971 0 : if (filter == NULL) {
2972 0 : ret = NT_STATUS_NO_MEMORY;
2973 0 : goto done;
2974 : }
2975 :
2976 0 : rc = smbldap_search(conn, lp_ldap_suffix(),
2977 : LDAP_SCOPE_SUBTREE, filter, attrs, 0, &result);
2978 :
2979 0 : if (rc != LDAP_SUCCESS)
2980 0 : goto done;
2981 :
2982 0 : smbldap_talloc_autofree_ldapmsg(mem_ctx, result);
2983 :
2984 0 : num_gids = 0;
2985 0 : *pp_gids = NULL;
2986 :
2987 0 : num_sids = 0;
2988 0 : *pp_sids = NULL;
2989 :
2990 : /* We need to add the primary group as the first gid/sid */
2991 :
2992 0 : if (!add_gid_to_array_unique(mem_ctx, primary_gid, pp_gids, &num_gids)) {
2993 0 : ret = NT_STATUS_NO_MEMORY;
2994 0 : goto done;
2995 : }
2996 :
2997 : /* This sid will be replaced later */
2998 :
2999 0 : ret = add_sid_to_array_unique(mem_ctx, &global_sid_NULL, pp_sids,
3000 : &num_sids);
3001 0 : if (!NT_STATUS_IS_OK(ret)) {
3002 0 : goto done;
3003 : }
3004 :
3005 0 : for (entry = ldap_first_entry(smbldap_get_ldap(conn), result);
3006 0 : entry != NULL;
3007 0 : entry = ldap_next_entry(smbldap_get_ldap(conn), entry))
3008 : {
3009 : fstring str;
3010 : struct dom_sid sid;
3011 : gid_t gid;
3012 :
3013 0 : if (!smbldap_get_single_attribute(smbldap_get_ldap(conn),
3014 : entry, "sambaSID",
3015 : str, sizeof(str)-1))
3016 0 : continue;
3017 :
3018 0 : if (!string_to_sid(&sid, str))
3019 0 : goto done;
3020 :
3021 0 : if (!smbldap_get_single_attribute(smbldap_get_ldap(conn),
3022 : entry, "gidNumber",
3023 : str, sizeof(str)-1))
3024 0 : continue;
3025 :
3026 0 : gid = smb_strtoul(str, NULL, 10, &error, SMB_STR_FULL_STR_CONV);
3027 :
3028 0 : if (error != 0) {
3029 0 : goto done;
3030 : }
3031 :
3032 0 : if (gid == primary_gid) {
3033 0 : sid_copy(&(*pp_sids)[0], &sid);
3034 : } else {
3035 0 : if (!add_gid_to_array_unique(mem_ctx, gid, pp_gids,
3036 : &num_gids)) {
3037 0 : ret = NT_STATUS_NO_MEMORY;
3038 0 : goto done;
3039 : }
3040 0 : ret = add_sid_to_array_unique(mem_ctx, &sid, pp_sids,
3041 : &num_sids);
3042 0 : if (!NT_STATUS_IS_OK(ret)) {
3043 0 : goto done;
3044 : }
3045 : }
3046 : }
3047 :
3048 0 : if (dom_sid_compare(&global_sid_NULL, &(*pp_sids)[0]) == 0) {
3049 0 : DEBUG(3, ("primary group of [%s] not found\n",
3050 : pdb_get_username(user)));
3051 0 : ret = NT_STATUS_INTERNAL_DB_CORRUPTION;
3052 0 : goto done;
3053 : }
3054 :
3055 0 : *p_num_groups = num_sids;
3056 :
3057 0 : ret = NT_STATUS_OK;
3058 :
3059 0 : done:
3060 :
3061 0 : TALLOC_FREE(escape_name);
3062 0 : return ret;
3063 : }
3064 :
3065 : /**********************************************************************
3066 : * Augment a posixGroup object with a sambaGroupMapping domgroup
3067 : *********************************************************************/
3068 :
3069 0 : static NTSTATUS ldapsam_map_posixgroup(TALLOC_CTX *mem_ctx,
3070 : struct ldapsam_privates *ldap_state,
3071 : GROUP_MAP *map)
3072 : {
3073 : const char *filter, *dn;
3074 : LDAPMessage *msg, *entry;
3075 : LDAPMod **mods;
3076 : struct dom_sid_buf buf;
3077 : int rc;
3078 :
3079 0 : filter = talloc_asprintf(mem_ctx,
3080 : "(&(objectClass=%s)(gidNumber=%u))",
3081 0 : LDAP_OBJ_POSIXGROUP, (unsigned int)map->gid);
3082 0 : if (filter == NULL) {
3083 0 : return NT_STATUS_NO_MEMORY;
3084 : }
3085 :
3086 0 : rc = smbldap_search_suffix(ldap_state->smbldap_state, filter,
3087 : get_attr_list(mem_ctx, groupmap_attr_list),
3088 : &msg);
3089 0 : smbldap_talloc_autofree_ldapmsg(mem_ctx, msg);
3090 :
3091 0 : if ((rc != LDAP_SUCCESS) ||
3092 0 : (ldap_count_entries(smbldap_get_ldap(ldap_state->smbldap_state),
3093 0 : msg) != 1) ||
3094 0 : ((entry = ldap_first_entry(
3095 : smbldap_get_ldap(ldap_state->smbldap_state),
3096 : msg)) == NULL)) {
3097 0 : return NT_STATUS_NO_SUCH_GROUP;
3098 : }
3099 :
3100 0 : dn = smbldap_talloc_dn(mem_ctx,
3101 : smbldap_get_ldap(ldap_state->smbldap_state),
3102 : entry);
3103 0 : if (dn == NULL) {
3104 0 : return NT_STATUS_NO_MEMORY;
3105 : }
3106 :
3107 0 : mods = NULL;
3108 0 : smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectClass",
3109 : LDAP_OBJ_GROUPMAP);
3110 0 : smbldap_make_mod(smbldap_get_ldap(ldap_state->smbldap_state), entry,
3111 : &mods, "sambaSid",
3112 0 : dom_sid_str_buf(&map->sid, &buf));
3113 0 : smbldap_make_mod(smbldap_get_ldap(ldap_state->smbldap_state), entry,
3114 : &mods, "sambaGroupType",
3115 0 : talloc_asprintf(mem_ctx, "%d", map->sid_name_use));
3116 0 : smbldap_make_mod(smbldap_get_ldap(ldap_state->smbldap_state), entry,
3117 : &mods, "displayName",
3118 0 : map->nt_name);
3119 0 : smbldap_make_mod(smbldap_get_ldap(ldap_state->smbldap_state), entry,
3120 : &mods, "description",
3121 0 : map->comment);
3122 0 : smbldap_talloc_autofree_ldapmod(mem_ctx, mods);
3123 :
3124 0 : rc = smbldap_modify(ldap_state->smbldap_state, dn, mods);
3125 0 : if (rc != LDAP_SUCCESS) {
3126 0 : return NT_STATUS_ACCESS_DENIED;
3127 : }
3128 :
3129 0 : return NT_STATUS_OK;
3130 : }
3131 :
3132 0 : static NTSTATUS ldapsam_add_group_mapping_entry(struct pdb_methods *methods,
3133 : GROUP_MAP *map)
3134 : {
3135 0 : struct ldapsam_privates *ldap_state =
3136 : (struct ldapsam_privates *)methods->private_data;
3137 0 : LDAPMessage *msg = NULL;
3138 0 : LDAPMod **mods = NULL;
3139 0 : const char *attrs[] = { NULL };
3140 : char *filter;
3141 :
3142 : char *dn;
3143 : TALLOC_CTX *mem_ctx;
3144 : NTSTATUS result;
3145 :
3146 : struct dom_sid sid;
3147 : struct dom_sid_buf buf;
3148 : struct unixid id;
3149 :
3150 : int rc;
3151 :
3152 0 : mem_ctx = talloc_new(NULL);
3153 0 : if (mem_ctx == NULL) {
3154 0 : DEBUG(0, ("talloc_new failed\n"));
3155 0 : return NT_STATUS_NO_MEMORY;
3156 : }
3157 :
3158 0 : filter = talloc_asprintf(mem_ctx, "(sambaSid=%s)",
3159 0 : dom_sid_str_buf(&map->sid, &buf));
3160 0 : if (filter == NULL) {
3161 0 : result = NT_STATUS_NO_MEMORY;
3162 0 : goto done;
3163 : }
3164 :
3165 0 : rc = smbldap_search(ldap_state->smbldap_state, lp_ldap_suffix(),
3166 : LDAP_SCOPE_SUBTREE, filter, attrs, True, &msg);
3167 0 : smbldap_talloc_autofree_ldapmsg(mem_ctx, msg);
3168 :
3169 0 : if ((rc == LDAP_SUCCESS) &&
3170 0 : (ldap_count_entries(smbldap_get_ldap(ldap_state->smbldap_state),
3171 : msg) > 0)) {
3172 :
3173 0 : DEBUG(3, ("SID %s already present in LDAP, refusing to add "
3174 : "group mapping entry\n",
3175 : dom_sid_str_buf(&map->sid, &buf)));
3176 0 : result = NT_STATUS_GROUP_EXISTS;
3177 0 : goto done;
3178 : }
3179 :
3180 0 : switch (map->sid_name_use) {
3181 :
3182 0 : case SID_NAME_DOM_GRP:
3183 : /* To map a domain group we need to have a posix group
3184 : to attach to. */
3185 0 : result = ldapsam_map_posixgroup(mem_ctx, ldap_state, map);
3186 0 : goto done;
3187 : break;
3188 :
3189 0 : case SID_NAME_ALIAS:
3190 0 : if (!sid_check_is_in_our_sam(&map->sid)
3191 0 : && !sid_check_is_in_builtin(&map->sid) )
3192 : {
3193 0 : DEBUG(3, ("Refusing to map sid %s as an alias, not in our domain\n",
3194 : dom_sid_str_buf(&map->sid, &buf)));
3195 0 : result = NT_STATUS_INVALID_PARAMETER;
3196 0 : goto done;
3197 : }
3198 0 : break;
3199 :
3200 0 : default:
3201 0 : DEBUG(3, ("Got invalid use '%s' for mapping\n",
3202 : sid_type_lookup(map->sid_name_use)));
3203 0 : result = NT_STATUS_INVALID_PARAMETER;
3204 0 : goto done;
3205 : }
3206 :
3207 : /* Domain groups have been mapped in a separate routine, we have to
3208 : * create an alias now */
3209 :
3210 0 : if (map->gid == -1) {
3211 0 : DEBUG(10, ("Refusing to map gid==-1\n"));
3212 0 : result = NT_STATUS_INVALID_PARAMETER;
3213 0 : goto done;
3214 : }
3215 :
3216 0 : id.id = map->gid;
3217 0 : id.type = ID_TYPE_GID;
3218 :
3219 0 : if (pdb_id_to_sid(&id, &sid)) {
3220 0 : DEBUG(3, ("Gid %u is already mapped to SID %s, refusing to "
3221 : "add\n",
3222 : (unsigned int)map->gid,
3223 : dom_sid_str_buf(&sid, &buf)));
3224 0 : result = NT_STATUS_GROUP_EXISTS;
3225 0 : goto done;
3226 : }
3227 :
3228 : /* Ok, enough checks done. It's still racy to go ahead now, but that's
3229 : * the best we can get out of LDAP. */
3230 :
3231 0 : dn = talloc_asprintf(mem_ctx, "sambaSid=%s,%s",
3232 0 : dom_sid_str_buf(&map->sid, &buf),
3233 : lp_ldap_group_suffix(talloc_tos()));
3234 0 : if (dn == NULL) {
3235 0 : result = NT_STATUS_NO_MEMORY;
3236 0 : goto done;
3237 : }
3238 :
3239 0 : mods = NULL;
3240 :
3241 0 : smbldap_make_mod(smbldap_get_ldap(ldap_state->smbldap_state), NULL,
3242 : &mods, "objectClass", LDAP_OBJ_SID_ENTRY);
3243 0 : smbldap_make_mod(smbldap_get_ldap(ldap_state->smbldap_state), NULL,
3244 : &mods, "objectClass", LDAP_OBJ_GROUPMAP);
3245 0 : smbldap_make_mod(smbldap_get_ldap(ldap_state->smbldap_state), NULL,
3246 : &mods, "sambaSid",
3247 0 : dom_sid_str_buf(&map->sid, &buf));
3248 0 : smbldap_make_mod(smbldap_get_ldap(ldap_state->smbldap_state), NULL,
3249 : &mods, "sambaGroupType",
3250 0 : talloc_asprintf(mem_ctx, "%d", map->sid_name_use));
3251 0 : smbldap_make_mod(smbldap_get_ldap(ldap_state->smbldap_state), NULL,
3252 : &mods, "displayName",
3253 0 : map->nt_name);
3254 0 : smbldap_make_mod(smbldap_get_ldap(ldap_state->smbldap_state), NULL,
3255 : &mods, "description",
3256 0 : map->comment);
3257 0 : smbldap_make_mod(smbldap_get_ldap(ldap_state->smbldap_state), NULL,
3258 : &mods, "gidNumber",
3259 0 : talloc_asprintf(mem_ctx, "%u",
3260 0 : (unsigned int)map->gid));
3261 0 : smbldap_talloc_autofree_ldapmod(mem_ctx, mods);
3262 :
3263 0 : rc = smbldap_add(ldap_state->smbldap_state, dn, mods);
3264 :
3265 0 : result = (rc == LDAP_SUCCESS) ?
3266 0 : NT_STATUS_OK : NT_STATUS_ACCESS_DENIED;
3267 :
3268 0 : done:
3269 0 : TALLOC_FREE(mem_ctx);
3270 0 : return result;
3271 : }
3272 :
3273 : /**********************************************************************
3274 : * Update a group mapping entry. We're quite strict about what can be changed:
3275 : * Only the description and displayname may be changed. It simply does not
3276 : * make any sense to change the SID, gid or the type in a mapping.
3277 : *********************************************************************/
3278 :
3279 0 : static NTSTATUS ldapsam_update_group_mapping_entry(struct pdb_methods *methods,
3280 : GROUP_MAP *map)
3281 : {
3282 0 : struct ldapsam_privates *ldap_state =
3283 : (struct ldapsam_privates *)methods->private_data;
3284 : int rc;
3285 : const char *filter, *dn;
3286 0 : LDAPMessage *msg = NULL;
3287 0 : LDAPMessage *entry = NULL;
3288 0 : LDAPMod **mods = NULL;
3289 : TALLOC_CTX *mem_ctx;
3290 : NTSTATUS result;
3291 : struct dom_sid_buf buf;
3292 :
3293 0 : mem_ctx = talloc_new(NULL);
3294 0 : if (mem_ctx == NULL) {
3295 0 : DEBUG(0, ("talloc_new failed\n"));
3296 0 : return NT_STATUS_NO_MEMORY;
3297 : }
3298 :
3299 : /* Make 100% sure that sid, gid and type are not changed by looking up
3300 : * exactly the values we're given in LDAP. */
3301 :
3302 0 : filter = talloc_asprintf(mem_ctx, "(&(objectClass=%s)"
3303 : "(sambaSid=%s)(gidNumber=%u)"
3304 : "(sambaGroupType=%d))",
3305 : LDAP_OBJ_GROUPMAP,
3306 0 : dom_sid_str_buf(&map->sid, &buf),
3307 0 : (unsigned int)map->gid, map->sid_name_use);
3308 0 : if (filter == NULL) {
3309 0 : result = NT_STATUS_NO_MEMORY;
3310 0 : goto done;
3311 : }
3312 :
3313 0 : rc = smbldap_search_suffix(ldap_state->smbldap_state, filter,
3314 : get_attr_list(mem_ctx, groupmap_attr_list),
3315 : &msg);
3316 0 : smbldap_talloc_autofree_ldapmsg(mem_ctx, msg);
3317 :
3318 0 : if ((rc != LDAP_SUCCESS) ||
3319 0 : (ldap_count_entries(smbldap_get_ldap(ldap_state->smbldap_state),
3320 0 : msg) != 1) ||
3321 0 : ((entry = ldap_first_entry(
3322 : smbldap_get_ldap(ldap_state->smbldap_state),
3323 : msg)) == NULL)) {
3324 0 : result = NT_STATUS_NO_SUCH_GROUP;
3325 0 : goto done;
3326 : }
3327 :
3328 0 : dn = smbldap_talloc_dn(
3329 : mem_ctx, smbldap_get_ldap(ldap_state->smbldap_state), entry);
3330 :
3331 0 : if (dn == NULL) {
3332 0 : result = NT_STATUS_NO_MEMORY;
3333 0 : goto done;
3334 : }
3335 :
3336 0 : mods = NULL;
3337 0 : smbldap_make_mod(smbldap_get_ldap(ldap_state->smbldap_state), entry,
3338 0 : &mods, "displayName", map->nt_name);
3339 0 : smbldap_make_mod(smbldap_get_ldap(ldap_state->smbldap_state), entry,
3340 0 : &mods, "description", map->comment);
3341 0 : smbldap_talloc_autofree_ldapmod(mem_ctx, mods);
3342 :
3343 0 : if (mods == NULL) {
3344 0 : DEBUG(4, ("ldapsam_update_group_mapping_entry: mods is empty: "
3345 : "nothing to do\n"));
3346 0 : result = NT_STATUS_OK;
3347 0 : goto done;
3348 : }
3349 :
3350 0 : rc = smbldap_modify(ldap_state->smbldap_state, dn, mods);
3351 :
3352 0 : if (rc != LDAP_SUCCESS) {
3353 0 : result = NT_STATUS_ACCESS_DENIED;
3354 0 : goto done;
3355 : }
3356 :
3357 0 : DEBUG(2, ("ldapsam_update_group_mapping_entry: successfully modified "
3358 : "group %lu in LDAP\n", (unsigned long)map->gid));
3359 :
3360 0 : result = NT_STATUS_OK;
3361 :
3362 0 : done:
3363 0 : TALLOC_FREE(mem_ctx);
3364 0 : return result;
3365 : }
3366 :
3367 : /**********************************************************************
3368 : *********************************************************************/
3369 :
3370 0 : static NTSTATUS ldapsam_delete_group_mapping_entry(struct pdb_methods *methods,
3371 : struct dom_sid sid)
3372 : {
3373 0 : struct ldapsam_privates *priv =
3374 : (struct ldapsam_privates *)methods->private_data;
3375 : LDAPMessage *msg, *entry;
3376 : int rc;
3377 : NTSTATUS result;
3378 : TALLOC_CTX *mem_ctx;
3379 : char *filter;
3380 : struct dom_sid_buf buf;
3381 :
3382 0 : mem_ctx = talloc_new(NULL);
3383 0 : if (mem_ctx == NULL) {
3384 0 : DEBUG(0, ("talloc_new failed\n"));
3385 0 : return NT_STATUS_NO_MEMORY;
3386 : }
3387 :
3388 0 : filter = talloc_asprintf(mem_ctx, "(&(objectClass=%s)(%s=%s))",
3389 : LDAP_OBJ_GROUPMAP, LDAP_ATTRIBUTE_SID,
3390 : dom_sid_str_buf(&sid, &buf));
3391 0 : if (filter == NULL) {
3392 0 : result = NT_STATUS_NO_MEMORY;
3393 0 : goto done;
3394 : }
3395 0 : rc = smbldap_search_suffix(priv->smbldap_state, filter,
3396 : get_attr_list(mem_ctx, groupmap_attr_list),
3397 : &msg);
3398 0 : smbldap_talloc_autofree_ldapmsg(mem_ctx, msg);
3399 :
3400 0 : if ((rc != LDAP_SUCCESS) ||
3401 0 : (ldap_count_entries(priv2ld(priv), msg) != 1) ||
3402 0 : ((entry = ldap_first_entry(priv2ld(priv), msg)) == NULL)) {
3403 0 : result = NT_STATUS_NO_SUCH_GROUP;
3404 0 : goto done;
3405 : }
3406 :
3407 0 : rc = ldapsam_delete_entry(priv, mem_ctx, entry, LDAP_OBJ_GROUPMAP,
3408 : get_attr_list(mem_ctx,
3409 : groupmap_attr_list_to_delete));
3410 :
3411 0 : if ((rc == LDAP_NAMING_VIOLATION) ||
3412 0 : (rc == LDAP_NOT_ALLOWED_ON_RDN) ||
3413 : (rc == LDAP_OBJECT_CLASS_VIOLATION)) {
3414 0 : const char *attrs[] = { "sambaGroupType", "description",
3415 : "displayName", "sambaSIDList",
3416 : NULL };
3417 :
3418 : /* Second try. Don't delete the sambaSID attribute, this is
3419 : for "old" entries that are tacked on a winbind
3420 : sambaIdmapEntry. */
3421 :
3422 0 : rc = ldapsam_delete_entry(priv, mem_ctx, entry,
3423 : LDAP_OBJ_GROUPMAP, attrs);
3424 : }
3425 :
3426 0 : if ((rc == LDAP_NAMING_VIOLATION) ||
3427 0 : (rc == LDAP_NOT_ALLOWED_ON_RDN) ||
3428 : (rc == LDAP_OBJECT_CLASS_VIOLATION)) {
3429 0 : const char *attrs[] = { "sambaGroupType", "description",
3430 : "displayName", "sambaSIDList",
3431 : "gidNumber", NULL };
3432 :
3433 : /* Third try. This is a post-3.0.21 alias (containing only
3434 : * sambaSidEntry and sambaGroupMapping classes), we also have
3435 : * to delete the gidNumber attribute, only the sambaSidEntry
3436 : * remains */
3437 :
3438 0 : rc = ldapsam_delete_entry(priv, mem_ctx, entry,
3439 : LDAP_OBJ_GROUPMAP, attrs);
3440 : }
3441 :
3442 0 : result = (rc == LDAP_SUCCESS) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
3443 :
3444 0 : done:
3445 0 : TALLOC_FREE(mem_ctx);
3446 0 : return result;
3447 : }
3448 :
3449 : /**********************************************************************
3450 : *********************************************************************/
3451 :
3452 0 : static NTSTATUS ldapsam_setsamgrent(struct pdb_methods *my_methods,
3453 : bool update)
3454 : {
3455 0 : struct ldapsam_privates *ldap_state =
3456 : (struct ldapsam_privates *)my_methods->private_data;
3457 0 : char *filter = NULL;
3458 : int rc;
3459 : const char **attr_list;
3460 :
3461 0 : filter = talloc_asprintf(NULL, "(objectclass=%s)", LDAP_OBJ_GROUPMAP);
3462 0 : if (!filter) {
3463 0 : return NT_STATUS_NO_MEMORY;
3464 : }
3465 0 : attr_list = get_attr_list( NULL, groupmap_attr_list );
3466 0 : rc = smbldap_search(ldap_state->smbldap_state, lp_ldap_suffix(),
3467 : LDAP_SCOPE_SUBTREE, filter,
3468 : attr_list, 0, &ldap_state->result);
3469 0 : TALLOC_FREE(attr_list);
3470 :
3471 0 : if (rc != LDAP_SUCCESS) {
3472 0 : DEBUG(0, ("ldapsam_setsamgrent: LDAP search failed: %s\n",
3473 : ldap_err2string(rc)));
3474 0 : DEBUG(3, ("ldapsam_setsamgrent: Query was: %s, %s\n",
3475 : lp_ldap_suffix(), filter));
3476 0 : ldap_msgfree(ldap_state->result);
3477 0 : ldap_state->result = NULL;
3478 0 : TALLOC_FREE(filter);
3479 0 : return NT_STATUS_UNSUCCESSFUL;
3480 : }
3481 :
3482 0 : TALLOC_FREE(filter);
3483 :
3484 0 : DEBUG(2, ("ldapsam_setsamgrent: %d entries in the base!\n",
3485 : ldap_count_entries(
3486 : smbldap_get_ldap(ldap_state->smbldap_state),
3487 : ldap_state->result)));
3488 :
3489 0 : ldap_state->entry =
3490 0 : ldap_first_entry(smbldap_get_ldap(ldap_state->smbldap_state),
3491 : ldap_state->result);
3492 0 : ldap_state->index = 0;
3493 :
3494 0 : return NT_STATUS_OK;
3495 : }
3496 :
3497 : /**********************************************************************
3498 : *********************************************************************/
3499 :
3500 0 : static void ldapsam_endsamgrent(struct pdb_methods *my_methods)
3501 : {
3502 0 : ldapsam_endsampwent(my_methods);
3503 0 : }
3504 :
3505 : /**********************************************************************
3506 : *********************************************************************/
3507 :
3508 0 : static NTSTATUS ldapsam_getsamgrent(struct pdb_methods *my_methods,
3509 : GROUP_MAP *map)
3510 : {
3511 0 : NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
3512 0 : struct ldapsam_privates *ldap_state =
3513 : (struct ldapsam_privates *)my_methods->private_data;
3514 0 : bool bret = False;
3515 :
3516 0 : while (!bret) {
3517 0 : if (!ldap_state->entry)
3518 0 : return ret;
3519 :
3520 0 : ldap_state->index++;
3521 0 : bret = init_group_from_ldap(ldap_state, map,
3522 : ldap_state->entry);
3523 :
3524 0 : ldap_state->entry = ldap_next_entry(
3525 : smbldap_get_ldap(ldap_state->smbldap_state),
3526 : ldap_state->entry);
3527 : }
3528 :
3529 0 : return NT_STATUS_OK;
3530 : }
3531 :
3532 : /**********************************************************************
3533 : *********************************************************************/
3534 :
3535 0 : static NTSTATUS ldapsam_enum_group_mapping(struct pdb_methods *methods,
3536 : const struct dom_sid *domsid, enum lsa_SidType sid_name_use,
3537 : GROUP_MAP ***pp_rmap,
3538 : size_t *p_num_entries,
3539 : bool unix_only)
3540 : {
3541 0 : GROUP_MAP *map = NULL;
3542 0 : size_t entries = 0;
3543 :
3544 0 : *p_num_entries = 0;
3545 0 : *pp_rmap = NULL;
3546 :
3547 0 : if (!NT_STATUS_IS_OK(ldapsam_setsamgrent(methods, False))) {
3548 0 : DEBUG(0, ("ldapsam_enum_group_mapping: Unable to open "
3549 : "passdb\n"));
3550 0 : return NT_STATUS_ACCESS_DENIED;
3551 : }
3552 :
3553 : while (true) {
3554 :
3555 0 : map = talloc_zero(NULL, GROUP_MAP);
3556 0 : if (!map) {
3557 0 : return NT_STATUS_NO_MEMORY;
3558 : }
3559 :
3560 0 : if (!NT_STATUS_IS_OK(ldapsam_getsamgrent(methods, map))) {
3561 0 : TALLOC_FREE(map);
3562 0 : break;
3563 : }
3564 :
3565 0 : if (sid_name_use != SID_NAME_UNKNOWN &&
3566 0 : sid_name_use != map->sid_name_use) {
3567 0 : DEBUG(11,("ldapsam_enum_group_mapping: group %s is "
3568 : "not of the requested type\n",
3569 : map->nt_name));
3570 0 : continue;
3571 : }
3572 0 : if (unix_only == ENUM_ONLY_MAPPED && map->gid == -1) {
3573 0 : DEBUG(11,("ldapsam_enum_group_mapping: group %s is "
3574 : "non mapped\n", map->nt_name));
3575 0 : continue;
3576 : }
3577 :
3578 0 : *pp_rmap = talloc_realloc(NULL, *pp_rmap,
3579 : GROUP_MAP *, entries + 1);
3580 0 : if (!(*pp_rmap)) {
3581 0 : DEBUG(0,("ldapsam_enum_group_mapping: Unable to "
3582 : "enlarge group map!\n"));
3583 0 : return NT_STATUS_UNSUCCESSFUL;
3584 : }
3585 :
3586 0 : (*pp_rmap)[entries] = talloc_move((*pp_rmap), &map);
3587 :
3588 0 : entries += 1;
3589 : }
3590 :
3591 0 : ldapsam_endsamgrent(methods);
3592 :
3593 0 : *p_num_entries = entries;
3594 :
3595 0 : return NT_STATUS_OK;
3596 : }
3597 :
3598 0 : static NTSTATUS ldapsam_modify_aliasmem(struct pdb_methods *methods,
3599 : const struct dom_sid *alias,
3600 : const struct dom_sid *member,
3601 : int modop)
3602 : {
3603 0 : struct ldapsam_privates *ldap_state =
3604 : (struct ldapsam_privates *)methods->private_data;
3605 0 : char *dn = NULL;
3606 0 : LDAPMessage *result = NULL;
3607 0 : LDAPMessage *entry = NULL;
3608 : int count;
3609 0 : LDAPMod **mods = NULL;
3610 : int rc;
3611 0 : enum lsa_SidType type = SID_NAME_USE_NONE;
3612 : struct dom_sid_buf tmp;
3613 :
3614 0 : char *filter = NULL;
3615 :
3616 0 : if (sid_check_is_in_builtin(alias)) {
3617 0 : type = SID_NAME_ALIAS;
3618 : }
3619 :
3620 0 : if (sid_check_is_in_our_sam(alias)) {
3621 0 : type = SID_NAME_ALIAS;
3622 : }
3623 :
3624 0 : if (type == SID_NAME_USE_NONE) {
3625 : struct dom_sid_buf buf;
3626 0 : DEBUG(5, ("SID %s is neither in builtin nor in our domain!\n",
3627 : dom_sid_str_buf(alias, &buf)));
3628 0 : return NT_STATUS_NO_SUCH_ALIAS;
3629 : }
3630 :
3631 0 : if (asprintf(&filter,
3632 : "(&(objectClass=%s)(sambaSid=%s)(sambaGroupType=%d))",
3633 : LDAP_OBJ_GROUPMAP,
3634 : dom_sid_str_buf(alias, &tmp),
3635 : type) < 0) {
3636 0 : return NT_STATUS_NO_MEMORY;
3637 : }
3638 :
3639 0 : if (ldapsam_search_one_group(ldap_state, filter,
3640 : &result) != LDAP_SUCCESS) {
3641 0 : SAFE_FREE(filter);
3642 0 : return NT_STATUS_NO_SUCH_ALIAS;
3643 : }
3644 :
3645 0 : count = ldap_count_entries(smbldap_get_ldap(ldap_state->smbldap_state),
3646 : result);
3647 :
3648 0 : if (count < 1) {
3649 0 : DEBUG(4, ("ldapsam_modify_aliasmem: Did not find alias\n"));
3650 0 : ldap_msgfree(result);
3651 0 : SAFE_FREE(filter);
3652 0 : return NT_STATUS_NO_SUCH_ALIAS;
3653 : }
3654 :
3655 0 : if (count > 1) {
3656 0 : DEBUG(1, ("ldapsam_modify_aliasmem: Duplicate entries for "
3657 : "filter %s: count=%d\n", filter, count));
3658 0 : ldap_msgfree(result);
3659 0 : SAFE_FREE(filter);
3660 0 : return NT_STATUS_NO_SUCH_ALIAS;
3661 : }
3662 :
3663 0 : SAFE_FREE(filter);
3664 :
3665 0 : entry = ldap_first_entry(smbldap_get_ldap(ldap_state->smbldap_state),
3666 : result);
3667 :
3668 0 : if (!entry) {
3669 0 : ldap_msgfree(result);
3670 0 : return NT_STATUS_UNSUCCESSFUL;
3671 : }
3672 :
3673 0 : dn = smbldap_talloc_dn(talloc_tos(),
3674 : smbldap_get_ldap(ldap_state->smbldap_state),
3675 : entry);
3676 0 : if (!dn) {
3677 0 : ldap_msgfree(result);
3678 0 : return NT_STATUS_UNSUCCESSFUL;
3679 : }
3680 :
3681 0 : smbldap_set_mod(&mods, modop,
3682 : get_attr_key2string(groupmap_attr_list,
3683 : LDAP_ATTR_SID_LIST),
3684 0 : dom_sid_str_buf(member, &tmp));
3685 :
3686 0 : rc = smbldap_modify(ldap_state->smbldap_state, dn, mods);
3687 :
3688 0 : ldap_mods_free(mods, True);
3689 0 : ldap_msgfree(result);
3690 0 : TALLOC_FREE(dn);
3691 :
3692 0 : if (rc == LDAP_TYPE_OR_VALUE_EXISTS) {
3693 0 : return NT_STATUS_MEMBER_IN_ALIAS;
3694 : }
3695 :
3696 0 : if (rc == LDAP_NO_SUCH_ATTRIBUTE) {
3697 0 : return NT_STATUS_MEMBER_NOT_IN_ALIAS;
3698 : }
3699 :
3700 0 : if (rc != LDAP_SUCCESS) {
3701 0 : return NT_STATUS_UNSUCCESSFUL;
3702 : }
3703 :
3704 0 : return NT_STATUS_OK;
3705 : }
3706 :
3707 0 : static NTSTATUS ldapsam_add_aliasmem(struct pdb_methods *methods,
3708 : const struct dom_sid *alias,
3709 : const struct dom_sid *member)
3710 : {
3711 0 : return ldapsam_modify_aliasmem(methods, alias, member, LDAP_MOD_ADD);
3712 : }
3713 :
3714 0 : static NTSTATUS ldapsam_del_aliasmem(struct pdb_methods *methods,
3715 : const struct dom_sid *alias,
3716 : const struct dom_sid *member)
3717 : {
3718 0 : return ldapsam_modify_aliasmem(methods, alias, member,
3719 : LDAP_MOD_DELETE);
3720 : }
3721 :
3722 0 : static NTSTATUS ldapsam_enum_aliasmem(struct pdb_methods *methods,
3723 : const struct dom_sid *alias,
3724 : TALLOC_CTX *mem_ctx,
3725 : struct dom_sid **pp_members,
3726 : size_t *p_num_members)
3727 : {
3728 0 : struct ldapsam_privates *ldap_state =
3729 : (struct ldapsam_privates *)methods->private_data;
3730 0 : LDAPMessage *result = NULL;
3731 0 : LDAPMessage *entry = NULL;
3732 : int count;
3733 0 : char **values = NULL;
3734 : int i;
3735 0 : char *filter = NULL;
3736 0 : uint32_t num_members = 0;
3737 0 : enum lsa_SidType type = SID_NAME_USE_NONE;
3738 : struct dom_sid_buf tmp;
3739 :
3740 0 : *pp_members = NULL;
3741 0 : *p_num_members = 0;
3742 :
3743 0 : if (sid_check_is_in_builtin(alias)) {
3744 0 : type = SID_NAME_ALIAS;
3745 : }
3746 :
3747 0 : if (sid_check_is_in_our_sam(alias)) {
3748 0 : type = SID_NAME_ALIAS;
3749 : }
3750 :
3751 0 : if (type == SID_NAME_USE_NONE) {
3752 0 : DEBUG(5, ("SID %s is neither in builtin nor in our domain!\n",
3753 : dom_sid_str_buf(alias, &tmp)));
3754 0 : return NT_STATUS_NO_SUCH_ALIAS;
3755 : }
3756 :
3757 0 : if (asprintf(&filter,
3758 : "(&(objectClass=%s)(sambaSid=%s)(sambaGroupType=%d))",
3759 : LDAP_OBJ_GROUPMAP,
3760 : dom_sid_str_buf(alias, &tmp),
3761 : type) < 0) {
3762 0 : return NT_STATUS_NO_MEMORY;
3763 : }
3764 :
3765 0 : if (ldapsam_search_one_group(ldap_state, filter,
3766 : &result) != LDAP_SUCCESS) {
3767 0 : SAFE_FREE(filter);
3768 0 : return NT_STATUS_NO_SUCH_ALIAS;
3769 : }
3770 :
3771 0 : count = ldap_count_entries(smbldap_get_ldap(ldap_state->smbldap_state),
3772 : result);
3773 :
3774 0 : if (count < 1) {
3775 0 : DEBUG(4, ("ldapsam_enum_aliasmem: Did not find alias\n"));
3776 0 : ldap_msgfree(result);
3777 0 : SAFE_FREE(filter);
3778 0 : return NT_STATUS_NO_SUCH_ALIAS;
3779 : }
3780 :
3781 0 : if (count > 1) {
3782 0 : DEBUG(1, ("ldapsam_enum_aliasmem: Duplicate entries for "
3783 : "filter %s: count=%d\n", filter, count));
3784 0 : ldap_msgfree(result);
3785 0 : SAFE_FREE(filter);
3786 0 : return NT_STATUS_NO_SUCH_ALIAS;
3787 : }
3788 :
3789 0 : SAFE_FREE(filter);
3790 :
3791 0 : entry = ldap_first_entry(smbldap_get_ldap(ldap_state->smbldap_state),
3792 : result);
3793 :
3794 0 : if (!entry) {
3795 0 : ldap_msgfree(result);
3796 0 : return NT_STATUS_UNSUCCESSFUL;
3797 : }
3798 :
3799 0 : values = ldap_get_values(smbldap_get_ldap(ldap_state->smbldap_state),
3800 : entry,
3801 : get_attr_key2string(groupmap_attr_list,
3802 : LDAP_ATTR_SID_LIST));
3803 :
3804 0 : if (values == NULL) {
3805 0 : ldap_msgfree(result);
3806 0 : return NT_STATUS_OK;
3807 : }
3808 :
3809 0 : count = ldap_count_values(values);
3810 :
3811 0 : for (i=0; i<count; i++) {
3812 : struct dom_sid member;
3813 : NTSTATUS status;
3814 :
3815 0 : if (!string_to_sid(&member, values[i]))
3816 0 : continue;
3817 :
3818 0 : status = add_sid_to_array(mem_ctx, &member, pp_members,
3819 : &num_members);
3820 0 : if (!NT_STATUS_IS_OK(status)) {
3821 0 : ldap_value_free(values);
3822 0 : ldap_msgfree(result);
3823 0 : return status;
3824 : }
3825 : }
3826 :
3827 0 : *p_num_members = num_members;
3828 0 : ldap_value_free(values);
3829 0 : ldap_msgfree(result);
3830 :
3831 0 : return NT_STATUS_OK;
3832 : }
3833 :
3834 0 : static NTSTATUS ldapsam_alias_memberships(struct pdb_methods *methods,
3835 : TALLOC_CTX *mem_ctx,
3836 : const struct dom_sid *domain_sid,
3837 : const struct dom_sid *members,
3838 : size_t num_members,
3839 : uint32_t **pp_alias_rids,
3840 : size_t *p_num_alias_rids)
3841 : {
3842 0 : struct ldapsam_privates *ldap_state =
3843 : (struct ldapsam_privates *)methods->private_data;
3844 : LDAP *ldap_struct;
3845 :
3846 0 : const char *attrs[] = { LDAP_ATTRIBUTE_SID, NULL };
3847 :
3848 0 : LDAPMessage *result = NULL;
3849 0 : LDAPMessage *entry = NULL;
3850 : int i;
3851 : int rc;
3852 : char *filter;
3853 0 : enum lsa_SidType type = SID_NAME_USE_NONE;
3854 0 : bool is_builtin = false;
3855 0 : bool sid_added = false;
3856 :
3857 0 : *pp_alias_rids = NULL;
3858 0 : *p_num_alias_rids = 0;
3859 :
3860 0 : if (sid_check_is_builtin(domain_sid)) {
3861 0 : is_builtin = true;
3862 0 : type = SID_NAME_ALIAS;
3863 : }
3864 :
3865 0 : if (sid_check_is_our_sam(domain_sid)) {
3866 0 : type = SID_NAME_ALIAS;
3867 : }
3868 :
3869 0 : if (type == SID_NAME_USE_NONE) {
3870 : struct dom_sid_buf buf;
3871 0 : DEBUG(5, ("SID %s is neither builtin nor domain!\n",
3872 : dom_sid_str_buf(domain_sid, &buf)));
3873 0 : return NT_STATUS_UNSUCCESSFUL;
3874 : }
3875 :
3876 0 : if (num_members == 0) {
3877 0 : return NT_STATUS_OK;
3878 : }
3879 :
3880 0 : filter = talloc_asprintf(mem_ctx,
3881 : "(&(objectclass=%s)(sambaGroupType=%d)(|",
3882 : LDAP_OBJ_GROUPMAP, type);
3883 :
3884 0 : for (i=0; i<num_members; i++) {
3885 : struct dom_sid_buf buf;
3886 0 : filter = talloc_asprintf(mem_ctx, "%s(sambaSIDList=%s)",
3887 : filter,
3888 0 : dom_sid_str_buf(&members[i], &buf));
3889 : }
3890 :
3891 0 : filter = talloc_asprintf(mem_ctx, "%s))", filter);
3892 :
3893 0 : if (filter == NULL) {
3894 0 : return NT_STATUS_NO_MEMORY;
3895 : }
3896 :
3897 0 : if (is_builtin &&
3898 0 : ldap_state->search_cache.filter &&
3899 0 : strcmp(ldap_state->search_cache.filter, filter) == 0) {
3900 0 : filter = talloc_move(filter, &ldap_state->search_cache.filter);
3901 0 : result = ldap_state->search_cache.result;
3902 0 : ldap_state->search_cache.result = NULL;
3903 : } else {
3904 0 : rc = smbldap_search(ldap_state->smbldap_state, lp_ldap_suffix(),
3905 : LDAP_SCOPE_SUBTREE, filter, attrs, 0, &result);
3906 0 : if (rc != LDAP_SUCCESS) {
3907 0 : return NT_STATUS_UNSUCCESSFUL;
3908 : }
3909 0 : smbldap_talloc_autofree_ldapmsg(filter, result);
3910 : }
3911 :
3912 0 : ldap_struct = smbldap_get_ldap(ldap_state->smbldap_state);
3913 :
3914 0 : for (entry = ldap_first_entry(ldap_struct, result);
3915 0 : entry != NULL;
3916 0 : entry = ldap_next_entry(ldap_struct, entry))
3917 : {
3918 : fstring sid_str;
3919 : struct dom_sid sid;
3920 : uint32_t rid;
3921 :
3922 0 : if (!smbldap_get_single_attribute(ldap_struct, entry,
3923 : LDAP_ATTRIBUTE_SID,
3924 : sid_str,
3925 : sizeof(sid_str)-1))
3926 0 : continue;
3927 :
3928 0 : if (!string_to_sid(&sid, sid_str))
3929 0 : continue;
3930 :
3931 0 : if (!sid_peek_check_rid(domain_sid, &sid, &rid))
3932 0 : continue;
3933 :
3934 0 : sid_added = true;
3935 :
3936 0 : if (!add_rid_to_array_unique(mem_ctx, rid, pp_alias_rids,
3937 : p_num_alias_rids)) {
3938 0 : return NT_STATUS_NO_MEMORY;
3939 : }
3940 : }
3941 :
3942 0 : if (!is_builtin && !sid_added) {
3943 0 : TALLOC_FREE(ldap_state->search_cache.filter);
3944 : /*
3945 : * Note: result is a talloc child of filter because of the
3946 : * smbldap_talloc_autofree_ldapmsg() usage
3947 : */
3948 0 : ldap_state->search_cache.filter = talloc_move(ldap_state, &filter);
3949 0 : ldap_state->search_cache.result = result;
3950 : }
3951 :
3952 0 : return NT_STATUS_OK;
3953 : }
3954 :
3955 0 : static NTSTATUS ldapsam_set_account_policy_in_ldap(struct pdb_methods *methods,
3956 : enum pdb_policy_type type,
3957 : uint32_t value)
3958 : {
3959 0 : NTSTATUS ntstatus = NT_STATUS_UNSUCCESSFUL;
3960 : int rc;
3961 0 : LDAPMod **mods = NULL;
3962 : fstring value_string;
3963 0 : const char *policy_attr = NULL;
3964 :
3965 0 : struct ldapsam_privates *ldap_state =
3966 : (struct ldapsam_privates *)methods->private_data;
3967 :
3968 0 : DEBUG(10,("ldapsam_set_account_policy_in_ldap\n"));
3969 :
3970 0 : if (!ldap_state->domain_dn) {
3971 0 : return NT_STATUS_INVALID_PARAMETER;
3972 : }
3973 :
3974 0 : policy_attr = get_account_policy_attr(type);
3975 0 : if (policy_attr == NULL) {
3976 0 : DEBUG(0,("ldapsam_set_account_policy_in_ldap: invalid "
3977 : "policy\n"));
3978 0 : return ntstatus;
3979 : }
3980 :
3981 0 : slprintf(value_string, sizeof(value_string) - 1, "%i", value);
3982 :
3983 0 : smbldap_set_mod(&mods, LDAP_MOD_REPLACE, policy_attr, value_string);
3984 :
3985 0 : rc = smbldap_modify(ldap_state->smbldap_state, ldap_state->domain_dn,
3986 : mods);
3987 :
3988 0 : ldap_mods_free(mods, True);
3989 :
3990 0 : if (rc != LDAP_SUCCESS) {
3991 0 : return ntstatus;
3992 : }
3993 :
3994 0 : if (!cache_account_policy_set(type, value)) {
3995 0 : DEBUG(0,("ldapsam_set_account_policy_in_ldap: failed to "
3996 : "update local tdb cache\n"));
3997 0 : return ntstatus;
3998 : }
3999 :
4000 0 : return NT_STATUS_OK;
4001 : }
4002 :
4003 0 : static NTSTATUS ldapsam_set_account_policy(struct pdb_methods *methods,
4004 : enum pdb_policy_type type,
4005 : uint32_t value)
4006 : {
4007 0 : return ldapsam_set_account_policy_in_ldap(methods, type,
4008 : value);
4009 : }
4010 :
4011 0 : static NTSTATUS ldapsam_get_account_policy_from_ldap(struct pdb_methods *methods,
4012 : enum pdb_policy_type type,
4013 : uint32_t *value)
4014 : {
4015 0 : NTSTATUS ntstatus = NT_STATUS_UNSUCCESSFUL;
4016 0 : LDAPMessage *result = NULL;
4017 0 : LDAPMessage *entry = NULL;
4018 : int count;
4019 : int rc;
4020 0 : char **vals = NULL;
4021 : char *filter;
4022 0 : const char *policy_attr = NULL;
4023 :
4024 0 : struct ldapsam_privates *ldap_state =
4025 : (struct ldapsam_privates *)methods->private_data;
4026 :
4027 : const char *attrs[2];
4028 :
4029 0 : DEBUG(10,("ldapsam_get_account_policy_from_ldap\n"));
4030 :
4031 0 : if (!ldap_state->domain_dn) {
4032 0 : return NT_STATUS_INVALID_PARAMETER;
4033 : }
4034 :
4035 0 : policy_attr = get_account_policy_attr(type);
4036 0 : if (!policy_attr) {
4037 0 : DEBUG(0,("ldapsam_get_account_policy_from_ldap: invalid "
4038 : "policy index: %d\n", type));
4039 0 : return ntstatus;
4040 : }
4041 :
4042 0 : attrs[0] = policy_attr;
4043 0 : attrs[1] = NULL;
4044 :
4045 0 : filter = talloc_asprintf(talloc_tos(), "(objectClass=%s)", LDAP_OBJ_DOMINFO);
4046 0 : if (filter == NULL) {
4047 0 : return NT_STATUS_NO_MEMORY;
4048 : }
4049 0 : rc = smbldap_search(ldap_state->smbldap_state, ldap_state->domain_dn,
4050 : LDAP_SCOPE_BASE, filter, attrs, 0,
4051 : &result);
4052 0 : TALLOC_FREE(filter);
4053 0 : if (rc != LDAP_SUCCESS) {
4054 0 : return ntstatus;
4055 : }
4056 :
4057 0 : count = ldap_count_entries(priv2ld(ldap_state), result);
4058 0 : if (count < 1) {
4059 0 : goto out;
4060 : }
4061 :
4062 0 : entry = ldap_first_entry(priv2ld(ldap_state), result);
4063 0 : if (entry == NULL) {
4064 0 : goto out;
4065 : }
4066 :
4067 0 : vals = ldap_get_values(priv2ld(ldap_state), entry, policy_attr);
4068 0 : if (vals == NULL) {
4069 0 : goto out;
4070 : }
4071 :
4072 0 : *value = (uint32_t)atol(vals[0]);
4073 :
4074 0 : ntstatus = NT_STATUS_OK;
4075 :
4076 0 : out:
4077 0 : if (vals)
4078 0 : ldap_value_free(vals);
4079 0 : ldap_msgfree(result);
4080 :
4081 0 : return ntstatus;
4082 : }
4083 :
4084 : /* wrapper around ldapsam_get_account_policy_from_ldap(), handles tdb as cache
4085 :
4086 : - if user hasn't decided to use account policies inside LDAP just reuse the
4087 : old tdb values
4088 :
4089 : - if there is a valid cache entry, return that
4090 : - if there is an LDAP entry, update cache and return
4091 : - otherwise set to default, update cache and return
4092 :
4093 : Guenther
4094 : */
4095 0 : static NTSTATUS ldapsam_get_account_policy(struct pdb_methods *methods,
4096 : enum pdb_policy_type type,
4097 : uint32_t *value)
4098 : {
4099 : NTSTATUS ntstatus;
4100 :
4101 0 : if (cache_account_policy_get(type, value)) {
4102 0 : DEBUG(11,("ldapsam_get_account_policy: got valid value from "
4103 : "cache\n"));
4104 0 : return NT_STATUS_OK;
4105 : }
4106 :
4107 0 : ntstatus = ldapsam_get_account_policy_from_ldap(methods, type,
4108 : value);
4109 0 : if (NT_STATUS_IS_OK(ntstatus)) {
4110 0 : goto update_cache;
4111 : }
4112 :
4113 0 : DEBUG(10,("ldapsam_get_account_policy: failed to retrieve from "
4114 : "ldap\n"));
4115 :
4116 : #if 0
4117 : /* should we automagically migrate old tdb value here ? */
4118 : if (account_policy_get(type, value))
4119 : goto update_ldap;
4120 :
4121 : DEBUG(10,("ldapsam_get_account_policy: no tdb for %d, trying "
4122 : "default\n", type));
4123 : #endif
4124 :
4125 0 : if (!account_policy_get_default(type, value)) {
4126 0 : return ntstatus;
4127 : }
4128 :
4129 : /* update_ldap: */
4130 :
4131 0 : ntstatus = ldapsam_set_account_policy(methods, type, *value);
4132 0 : if (!NT_STATUS_IS_OK(ntstatus)) {
4133 0 : return ntstatus;
4134 : }
4135 :
4136 0 : update_cache:
4137 :
4138 0 : if (!cache_account_policy_set(type, *value)) {
4139 0 : DEBUG(0,("ldapsam_get_account_policy: failed to update local "
4140 : "tdb as a cache\n"));
4141 0 : return NT_STATUS_UNSUCCESSFUL;
4142 : }
4143 :
4144 0 : return NT_STATUS_OK;
4145 : }
4146 :
4147 0 : static NTSTATUS ldapsam_lookup_rids(struct pdb_methods *methods,
4148 : const struct dom_sid *domain_sid,
4149 : int num_rids,
4150 : uint32_t *rids,
4151 : const char **names,
4152 : enum lsa_SidType *attrs)
4153 : {
4154 0 : struct ldapsam_privates *ldap_state =
4155 : (struct ldapsam_privates *)methods->private_data;
4156 0 : LDAPMessage *msg = NULL;
4157 : LDAPMessage *entry;
4158 0 : char *allsids = NULL;
4159 : size_t i, num_mapped;
4160 : int rc;
4161 0 : NTSTATUS result = NT_STATUS_NO_MEMORY;
4162 : TALLOC_CTX *mem_ctx;
4163 : LDAP *ld;
4164 : bool is_builtin;
4165 :
4166 0 : mem_ctx = talloc_new(NULL);
4167 0 : if (mem_ctx == NULL) {
4168 0 : DEBUG(0, ("talloc_new failed\n"));
4169 0 : goto done;
4170 : }
4171 :
4172 0 : if (!sid_check_is_builtin(domain_sid) &&
4173 0 : !sid_check_is_our_sam(domain_sid)) {
4174 0 : result = NT_STATUS_INVALID_PARAMETER;
4175 0 : goto done;
4176 : }
4177 :
4178 0 : if (num_rids == 0) {
4179 0 : result = NT_STATUS_NONE_MAPPED;
4180 0 : goto done;
4181 : }
4182 :
4183 0 : for (i=0; i<num_rids; i++)
4184 0 : attrs[i] = SID_NAME_UNKNOWN;
4185 :
4186 0 : allsids = talloc_strdup(mem_ctx, "");
4187 0 : if (allsids == NULL) {
4188 0 : goto done;
4189 : }
4190 :
4191 0 : for (i=0; i<num_rids; i++) {
4192 : struct dom_sid sid;
4193 : struct dom_sid_buf buf;
4194 0 : sid_compose(&sid, domain_sid, rids[i]);
4195 0 : allsids = talloc_asprintf_append_buffer(
4196 : allsids,
4197 : "(sambaSid=%s)",
4198 : dom_sid_str_buf(&sid, &buf));
4199 0 : if (allsids == NULL) {
4200 0 : goto done;
4201 : }
4202 : }
4203 :
4204 : /* First look for users */
4205 :
4206 : {
4207 : char *filter;
4208 0 : const char *ldap_attrs[] = { "uid", "sambaSid", NULL };
4209 :
4210 0 : filter = talloc_asprintf(
4211 : mem_ctx, ("(&(objectClass=%s)(|%s))"),
4212 : LDAP_OBJ_SAMBASAMACCOUNT, allsids);
4213 :
4214 0 : if (filter == NULL) {
4215 0 : goto done;
4216 : }
4217 :
4218 0 : rc = smbldap_search(ldap_state->smbldap_state,
4219 : lp_ldap_user_suffix(talloc_tos()),
4220 : LDAP_SCOPE_SUBTREE, filter, ldap_attrs, 0,
4221 : &msg);
4222 0 : smbldap_talloc_autofree_ldapmsg(mem_ctx, msg);
4223 : }
4224 :
4225 0 : if (rc != LDAP_SUCCESS)
4226 0 : goto done;
4227 :
4228 0 : ld = smbldap_get_ldap(ldap_state->smbldap_state);
4229 0 : num_mapped = 0;
4230 :
4231 0 : for (entry = ldap_first_entry(ld, msg);
4232 0 : entry != NULL;
4233 0 : entry = ldap_next_entry(ld, entry)) {
4234 : uint32_t rid;
4235 : int rid_index;
4236 : const char *name;
4237 :
4238 0 : if (!ldapsam_extract_rid_from_entry(ld, entry, domain_sid,
4239 : &rid)) {
4240 0 : DEBUG(2, ("Could not find sid from ldap entry\n"));
4241 0 : continue;
4242 : }
4243 :
4244 0 : name = smbldap_talloc_single_attribute(ld, entry, "uid",
4245 : names);
4246 0 : if (name == NULL) {
4247 0 : DEBUG(2, ("Could not retrieve uid attribute\n"));
4248 0 : continue;
4249 : }
4250 :
4251 0 : for (rid_index = 0; rid_index < num_rids; rid_index++) {
4252 0 : if (rid == rids[rid_index])
4253 0 : break;
4254 : }
4255 :
4256 0 : if (rid_index == num_rids) {
4257 0 : DEBUG(2, ("Got a RID not asked for: %d\n", rid));
4258 0 : continue;
4259 : }
4260 :
4261 0 : attrs[rid_index] = SID_NAME_USER;
4262 0 : names[rid_index] = name;
4263 0 : num_mapped += 1;
4264 : }
4265 :
4266 0 : if (num_mapped == num_rids) {
4267 : /* No need to look for groups anymore -- we're done */
4268 0 : result = NT_STATUS_OK;
4269 0 : goto done;
4270 : }
4271 :
4272 : /* Same game for groups */
4273 :
4274 : {
4275 : char *filter;
4276 0 : const char *ldap_attrs[] = { "cn", "displayName", "sambaSid",
4277 : "sambaGroupType", NULL };
4278 :
4279 0 : filter = talloc_asprintf(
4280 : mem_ctx, "(&(objectClass=%s)(|%s))",
4281 : LDAP_OBJ_GROUPMAP, allsids);
4282 0 : if (filter == NULL) {
4283 0 : goto done;
4284 : }
4285 :
4286 0 : rc = smbldap_search(ldap_state->smbldap_state,
4287 : lp_ldap_suffix(),
4288 : LDAP_SCOPE_SUBTREE, filter, ldap_attrs, 0,
4289 : &msg);
4290 0 : smbldap_talloc_autofree_ldapmsg(mem_ctx, msg);
4291 : }
4292 :
4293 0 : if (rc != LDAP_SUCCESS)
4294 0 : goto done;
4295 :
4296 : /* ldap_struct might have changed due to a reconnect */
4297 :
4298 0 : ld = smbldap_get_ldap(ldap_state->smbldap_state);
4299 :
4300 : /* For consistency checks, we already checked we're only domain or builtin */
4301 :
4302 0 : is_builtin = sid_check_is_builtin(domain_sid);
4303 :
4304 0 : for (entry = ldap_first_entry(ld, msg);
4305 0 : entry != NULL;
4306 0 : entry = ldap_next_entry(ld, entry))
4307 : {
4308 : uint32_t rid;
4309 : int rid_index;
4310 : const char *attr;
4311 : enum lsa_SidType type;
4312 0 : const char *dn = smbldap_talloc_dn(mem_ctx, ld, entry);
4313 :
4314 0 : attr = smbldap_talloc_single_attribute(ld, entry, "sambaGroupType",
4315 : mem_ctx);
4316 0 : if (attr == NULL) {
4317 0 : DEBUG(2, ("Could not extract type from ldap entry %s\n",
4318 : dn));
4319 0 : continue;
4320 : }
4321 :
4322 0 : type = (enum lsa_SidType)atol(attr);
4323 :
4324 : /* Consistency checks */
4325 0 : if ((is_builtin && (type != SID_NAME_ALIAS)) ||
4326 0 : (!is_builtin && ((type != SID_NAME_ALIAS) &&
4327 : (type != SID_NAME_DOM_GRP)))) {
4328 0 : DEBUG(2, ("Rejecting invalid group mapping entry %s\n", dn));
4329 : }
4330 :
4331 0 : if (!ldapsam_extract_rid_from_entry(ld, entry, domain_sid,
4332 : &rid)) {
4333 0 : DEBUG(2, ("Could not find sid from ldap entry %s\n", dn));
4334 0 : continue;
4335 : }
4336 :
4337 0 : attr = smbldap_talloc_single_attribute(ld, entry, "displayName", names);
4338 :
4339 0 : if (attr == NULL) {
4340 0 : DEBUG(10, ("Could not retrieve 'displayName' attribute from %s\n",
4341 : dn));
4342 0 : attr = smbldap_talloc_single_attribute(ld, entry, "cn", names);
4343 : }
4344 :
4345 0 : if (attr == NULL) {
4346 0 : DEBUG(2, ("Could not retrieve naming attribute from %s\n",
4347 : dn));
4348 0 : continue;
4349 : }
4350 :
4351 0 : for (rid_index = 0; rid_index < num_rids; rid_index++) {
4352 0 : if (rid == rids[rid_index])
4353 0 : break;
4354 : }
4355 :
4356 0 : if (rid_index == num_rids) {
4357 0 : DEBUG(2, ("Got a RID not asked for: %d\n", rid));
4358 0 : continue;
4359 : }
4360 :
4361 0 : attrs[rid_index] = type;
4362 0 : names[rid_index] = attr;
4363 0 : num_mapped += 1;
4364 : }
4365 :
4366 0 : result = NT_STATUS_NONE_MAPPED;
4367 :
4368 0 : if (num_mapped > 0)
4369 0 : result = (num_mapped == num_rids) ?
4370 0 : NT_STATUS_OK : STATUS_SOME_UNMAPPED;
4371 0 : done:
4372 0 : TALLOC_FREE(mem_ctx);
4373 0 : return result;
4374 : }
4375 :
4376 0 : static char *get_ldap_filter(TALLOC_CTX *mem_ctx, const char *username)
4377 : {
4378 0 : char *filter = NULL;
4379 0 : char *escaped = NULL;
4380 0 : char *result = NULL;
4381 :
4382 0 : if (asprintf(&filter, "(&%s(objectclass=%s))",
4383 : "(uid=%u)", LDAP_OBJ_SAMBASAMACCOUNT) < 0) {
4384 0 : goto done;
4385 : }
4386 :
4387 0 : escaped = escape_ldap_string(talloc_tos(), username);
4388 0 : if (escaped == NULL) goto done;
4389 :
4390 0 : result = talloc_string_sub(mem_ctx, filter, "%u", username);
4391 :
4392 0 : done:
4393 0 : SAFE_FREE(filter);
4394 0 : TALLOC_FREE(escaped);
4395 :
4396 0 : return result;
4397 : }
4398 :
4399 0 : static const char **talloc_attrs(TALLOC_CTX *mem_ctx, ...)
4400 : {
4401 0 : int i, num = 0;
4402 : va_list ap;
4403 : const char **result;
4404 :
4405 0 : va_start(ap, mem_ctx);
4406 0 : while (va_arg(ap, const char *) != NULL)
4407 0 : num += 1;
4408 0 : va_end(ap);
4409 :
4410 0 : if ((result = talloc_array(mem_ctx, const char *, num+1)) == NULL) {
4411 0 : return NULL;
4412 : }
4413 :
4414 0 : va_start(ap, mem_ctx);
4415 0 : for (i=0; i<num; i++) {
4416 0 : result[i] = talloc_strdup(result, va_arg(ap, const char*));
4417 0 : if (result[i] == NULL) {
4418 0 : talloc_free(result);
4419 0 : va_end(ap);
4420 0 : return NULL;
4421 : }
4422 : }
4423 0 : va_end(ap);
4424 :
4425 0 : result[num] = NULL;
4426 0 : return result;
4427 : }
4428 :
4429 : struct ldap_search_state {
4430 : struct smbldap_state *connection;
4431 :
4432 : uint32_t acct_flags;
4433 : uint16_t group_type;
4434 :
4435 : const char *base;
4436 : int scope;
4437 : const char *filter;
4438 : const char **attrs;
4439 : int attrsonly;
4440 : void *pagedresults_cookie;
4441 :
4442 : LDAPMessage *entries, *current_entry;
4443 : bool (*ldap2displayentry)(struct ldap_search_state *state,
4444 : TALLOC_CTX *mem_ctx,
4445 : LDAP *ld, LDAPMessage *entry,
4446 : struct samr_displayentry *result);
4447 : };
4448 :
4449 0 : static bool ldapsam_search_firstpage(struct pdb_search *search)
4450 : {
4451 0 : struct ldap_search_state *state =
4452 : (struct ldap_search_state *)search->private_data;
4453 : LDAP *ld;
4454 0 : int rc = LDAP_OPERATIONS_ERROR;
4455 :
4456 0 : state->entries = NULL;
4457 :
4458 0 : if (smbldap_get_paged_results(state->connection)) {
4459 0 : rc = smbldap_search_paged(state->connection, state->base,
4460 : state->scope, state->filter,
4461 : state->attrs, state->attrsonly,
4462 : lp_ldap_page_size(), &state->entries,
4463 : &state->pagedresults_cookie);
4464 : }
4465 :
4466 0 : if ((rc != LDAP_SUCCESS) || (state->entries == NULL)) {
4467 :
4468 0 : if (state->entries != NULL) {
4469 : /* Left over from unsuccessful paged attempt */
4470 0 : ldap_msgfree(state->entries);
4471 0 : state->entries = NULL;
4472 : }
4473 :
4474 0 : rc = smbldap_search(state->connection, state->base,
4475 : state->scope, state->filter, state->attrs,
4476 : state->attrsonly, &state->entries);
4477 :
4478 0 : if ((rc != LDAP_SUCCESS) || (state->entries == NULL))
4479 0 : return False;
4480 :
4481 : /* Ok, the server was lying. It told us it could do paged
4482 : * searches when it could not. */
4483 0 : smbldap_set_paged_results(state->connection, false);
4484 : }
4485 :
4486 0 : ld = smbldap_get_ldap(state->connection);
4487 0 : if ( ld == NULL) {
4488 0 : DEBUG(5, ("Don't have an LDAP connection right after a "
4489 : "search\n"));
4490 0 : return False;
4491 : }
4492 0 : state->current_entry = ldap_first_entry(ld, state->entries);
4493 :
4494 0 : return True;
4495 : }
4496 :
4497 0 : static bool ldapsam_search_nextpage(struct pdb_search *search)
4498 : {
4499 0 : struct ldap_search_state *state =
4500 : (struct ldap_search_state *)search->private_data;
4501 : int rc;
4502 :
4503 0 : if (!smbldap_get_paged_results(state->connection)) {
4504 : /* There is no next page when there are no paged results */
4505 0 : return False;
4506 : }
4507 :
4508 0 : rc = smbldap_search_paged(state->connection, state->base,
4509 : state->scope, state->filter, state->attrs,
4510 : state->attrsonly, lp_ldap_page_size(),
4511 : &state->entries,
4512 : &state->pagedresults_cookie);
4513 :
4514 0 : if ((rc != LDAP_SUCCESS) || (state->entries == NULL))
4515 0 : return False;
4516 :
4517 0 : state->current_entry = ldap_first_entry(
4518 : smbldap_get_ldap(state->connection), state->entries);
4519 :
4520 0 : if (state->current_entry == NULL) {
4521 0 : ldap_msgfree(state->entries);
4522 0 : state->entries = NULL;
4523 0 : return false;
4524 : }
4525 :
4526 0 : return True;
4527 : }
4528 :
4529 0 : static bool ldapsam_search_next_entry(struct pdb_search *search,
4530 : struct samr_displayentry *entry)
4531 : {
4532 0 : struct ldap_search_state *state =
4533 : (struct ldap_search_state *)search->private_data;
4534 : bool result;
4535 :
4536 0 : retry:
4537 0 : if ((state->entries == NULL) && (state->pagedresults_cookie == NULL))
4538 0 : return False;
4539 :
4540 0 : if ((state->entries == NULL) &&
4541 0 : !ldapsam_search_nextpage(search))
4542 0 : return False;
4543 :
4544 0 : if (state->current_entry == NULL) {
4545 0 : return false;
4546 : }
4547 :
4548 0 : result = state->ldap2displayentry(state, search,
4549 : smbldap_get_ldap(state->connection),
4550 : state->current_entry, entry);
4551 :
4552 0 : if (!result) {
4553 : char *dn;
4554 0 : dn = ldap_get_dn(smbldap_get_ldap(state->connection),
4555 : state->current_entry);
4556 0 : DEBUG(5, ("Skipping entry %s\n", dn != NULL ? dn : "<NULL>"));
4557 0 : if (dn != NULL) ldap_memfree(dn);
4558 : }
4559 :
4560 0 : state->current_entry = ldap_next_entry(
4561 : smbldap_get_ldap(state->connection), state->current_entry);
4562 :
4563 0 : if (state->current_entry == NULL) {
4564 0 : ldap_msgfree(state->entries);
4565 0 : state->entries = NULL;
4566 : }
4567 :
4568 0 : if (!result) goto retry;
4569 :
4570 0 : return True;
4571 : }
4572 :
4573 0 : static void ldapsam_search_end(struct pdb_search *search)
4574 : {
4575 0 : struct ldap_search_state *state =
4576 : (struct ldap_search_state *)search->private_data;
4577 : int rc;
4578 :
4579 0 : if (state->pagedresults_cookie == NULL)
4580 0 : return;
4581 :
4582 0 : if (state->entries != NULL)
4583 0 : ldap_msgfree(state->entries);
4584 :
4585 0 : state->entries = NULL;
4586 0 : state->current_entry = NULL;
4587 :
4588 0 : if (!smbldap_get_paged_results(state->connection)) {
4589 0 : return;
4590 : }
4591 :
4592 : /* Tell the LDAP server we're not interested in the rest anymore. */
4593 :
4594 0 : rc = smbldap_search_paged(state->connection, state->base, state->scope,
4595 : state->filter, state->attrs,
4596 : state->attrsonly, 0, &state->entries,
4597 : &state->pagedresults_cookie);
4598 :
4599 0 : if (rc != LDAP_SUCCESS)
4600 0 : DEBUG(5, ("Could not end search properly\n"));
4601 :
4602 0 : return;
4603 : }
4604 :
4605 0 : static bool ldapuser2displayentry(struct ldap_search_state *state,
4606 : TALLOC_CTX *mem_ctx,
4607 : LDAP *ld, LDAPMessage *entry,
4608 : struct samr_displayentry *result)
4609 : {
4610 : char **vals;
4611 : size_t converted_size;
4612 : struct dom_sid sid;
4613 : uint32_t acct_flags;
4614 :
4615 0 : vals = ldap_get_values(ld, entry, "sambaAcctFlags");
4616 0 : if ((vals == NULL) || (vals[0] == NULL)) {
4617 0 : acct_flags = ACB_NORMAL;
4618 : } else {
4619 0 : acct_flags = pdb_decode_acct_ctrl(vals[0]);
4620 0 : ldap_value_free(vals);
4621 : }
4622 :
4623 0 : if ((state->acct_flags != 0) &&
4624 0 : ((state->acct_flags & acct_flags) == 0))
4625 0 : return False;
4626 :
4627 0 : result->acct_flags = acct_flags;
4628 0 : result->account_name = "";
4629 0 : result->fullname = "";
4630 0 : result->description = "";
4631 :
4632 0 : vals = ldap_get_values(ld, entry, "uid");
4633 0 : if ((vals == NULL) || (vals[0] == NULL)) {
4634 0 : DEBUG(5, ("\"uid\" not found\n"));
4635 0 : return False;
4636 : }
4637 0 : if (!pull_utf8_talloc(mem_ctx,
4638 0 : discard_const_p(char *, &result->account_name),
4639 : vals[0], &converted_size))
4640 : {
4641 0 : DEBUG(0,("ldapuser2displayentry: pull_utf8_talloc failed: %s",
4642 : strerror(errno)));
4643 : }
4644 :
4645 0 : ldap_value_free(vals);
4646 :
4647 0 : vals = ldap_get_values(ld, entry, "displayName");
4648 0 : if ((vals == NULL) || (vals[0] == NULL))
4649 0 : DEBUG(8, ("\"displayName\" not found\n"));
4650 0 : else if (!pull_utf8_talloc(mem_ctx,
4651 0 : discard_const_p(char *, &result->fullname),
4652 : vals[0], &converted_size))
4653 : {
4654 0 : DEBUG(0,("ldapuser2displayentry: pull_utf8_talloc failed: %s",
4655 : strerror(errno)));
4656 : }
4657 :
4658 0 : ldap_value_free(vals);
4659 :
4660 0 : vals = ldap_get_values(ld, entry, "description");
4661 0 : if ((vals == NULL) || (vals[0] == NULL))
4662 0 : DEBUG(8, ("\"description\" not found\n"));
4663 0 : else if (!pull_utf8_talloc(mem_ctx,
4664 0 : discard_const_p(char *, &result->description),
4665 : vals[0], &converted_size))
4666 : {
4667 0 : DEBUG(0,("ldapuser2displayentry: pull_utf8_talloc failed: %s",
4668 : strerror(errno)));
4669 : }
4670 :
4671 0 : ldap_value_free(vals);
4672 :
4673 0 : if ((result->account_name == NULL) ||
4674 0 : (result->fullname == NULL) ||
4675 0 : (result->description == NULL)) {
4676 0 : DEBUG(0, ("talloc failed\n"));
4677 0 : return False;
4678 : }
4679 :
4680 0 : vals = ldap_get_values(ld, entry, "sambaSid");
4681 0 : if ((vals == NULL) || (vals[0] == NULL)) {
4682 0 : DEBUG(0, ("\"objectSid\" not found\n"));
4683 0 : return False;
4684 : }
4685 :
4686 0 : if (!string_to_sid(&sid, vals[0])) {
4687 0 : DEBUG(0, ("Could not convert %s to SID\n", vals[0]));
4688 0 : ldap_value_free(vals);
4689 0 : return False;
4690 : }
4691 0 : ldap_value_free(vals);
4692 :
4693 0 : if (!sid_peek_check_rid(get_global_sam_sid(), &sid, &result->rid)) {
4694 : struct dom_sid_buf buf;
4695 0 : DEBUG(0, ("sid %s does not belong to our domain\n",
4696 : dom_sid_str_buf(&sid, &buf)));
4697 0 : return False;
4698 : }
4699 :
4700 0 : return True;
4701 : }
4702 :
4703 :
4704 0 : static bool ldapsam_search_users(struct pdb_methods *methods,
4705 : struct pdb_search *search,
4706 : uint32_t acct_flags)
4707 : {
4708 0 : struct ldapsam_privates *ldap_state =
4709 : (struct ldapsam_privates *)methods->private_data;
4710 : struct ldap_search_state *state;
4711 :
4712 0 : state = talloc(search, struct ldap_search_state);
4713 0 : if (state == NULL) {
4714 0 : DEBUG(0, ("talloc failed\n"));
4715 0 : return False;
4716 : }
4717 :
4718 0 : state->connection = ldap_state->smbldap_state;
4719 :
4720 0 : if ((acct_flags != 0) && ((acct_flags & ACB_NORMAL) != 0))
4721 0 : state->base = lp_ldap_user_suffix(talloc_tos());
4722 0 : else if ((acct_flags != 0) &&
4723 0 : ((acct_flags & (ACB_WSTRUST|ACB_SVRTRUST|ACB_DOMTRUST)) != 0))
4724 0 : state->base = lp_ldap_machine_suffix(talloc_tos());
4725 : else
4726 0 : state->base = lp_ldap_suffix();
4727 :
4728 0 : state->acct_flags = acct_flags;
4729 0 : state->base = talloc_strdup(search, state->base);
4730 0 : state->scope = LDAP_SCOPE_SUBTREE;
4731 0 : state->filter = get_ldap_filter(search, "*");
4732 0 : state->attrs = talloc_attrs(search, "uid", "sambaSid",
4733 : "displayName", "description",
4734 : "sambaAcctFlags", NULL);
4735 0 : state->attrsonly = 0;
4736 0 : state->pagedresults_cookie = NULL;
4737 0 : state->entries = NULL;
4738 0 : state->ldap2displayentry = ldapuser2displayentry;
4739 :
4740 0 : if ((state->filter == NULL) || (state->attrs == NULL)) {
4741 0 : DEBUG(0, ("talloc failed\n"));
4742 0 : return False;
4743 : }
4744 :
4745 0 : search->private_data = state;
4746 0 : search->next_entry = ldapsam_search_next_entry;
4747 0 : search->search_end = ldapsam_search_end;
4748 :
4749 0 : return ldapsam_search_firstpage(search);
4750 : }
4751 :
4752 0 : static bool ldapgroup2displayentry(struct ldap_search_state *state,
4753 : TALLOC_CTX *mem_ctx,
4754 : LDAP *ld, LDAPMessage *entry,
4755 : struct samr_displayentry *result)
4756 : {
4757 : char **vals;
4758 : size_t converted_size;
4759 : struct dom_sid sid;
4760 : uint16_t group_type;
4761 :
4762 0 : result->account_name = "";
4763 0 : result->fullname = "";
4764 0 : result->description = "";
4765 :
4766 :
4767 0 : vals = ldap_get_values(ld, entry, "sambaGroupType");
4768 0 : if ((vals == NULL) || (vals[0] == NULL)) {
4769 0 : DEBUG(5, ("\"sambaGroupType\" not found\n"));
4770 0 : if (vals != NULL) {
4771 0 : ldap_value_free(vals);
4772 : }
4773 0 : return False;
4774 : }
4775 :
4776 0 : group_type = atoi(vals[0]);
4777 :
4778 0 : if ((state->group_type != 0) &&
4779 0 : ((state->group_type != group_type))) {
4780 0 : ldap_value_free(vals);
4781 0 : return False;
4782 : }
4783 :
4784 0 : ldap_value_free(vals);
4785 :
4786 : /* display name is the NT group name */
4787 :
4788 0 : vals = ldap_get_values(ld, entry, "displayName");
4789 0 : if ((vals == NULL) || (vals[0] == NULL)) {
4790 0 : DEBUG(8, ("\"displayName\" not found\n"));
4791 :
4792 : /* fallback to the 'cn' attribute */
4793 0 : vals = ldap_get_values(ld, entry, "cn");
4794 0 : if ((vals == NULL) || (vals[0] == NULL)) {
4795 0 : DEBUG(5, ("\"cn\" not found\n"));
4796 0 : return False;
4797 : }
4798 0 : if (!pull_utf8_talloc(mem_ctx,
4799 0 : discard_const_p(char *,
4800 : &result->account_name),
4801 : vals[0], &converted_size))
4802 : {
4803 0 : DEBUG(0,("ldapgroup2displayentry: pull_utf8_talloc "
4804 : "failed: %s", strerror(errno)));
4805 : }
4806 : }
4807 0 : else if (!pull_utf8_talloc(mem_ctx,
4808 0 : discard_const_p(char *,
4809 : &result->account_name),
4810 : vals[0], &converted_size))
4811 : {
4812 0 : DEBUG(0,("ldapgroup2displayentry: pull_utf8_talloc failed: %s",
4813 : strerror(errno)));
4814 : }
4815 :
4816 0 : ldap_value_free(vals);
4817 :
4818 0 : vals = ldap_get_values(ld, entry, "description");
4819 0 : if ((vals == NULL) || (vals[0] == NULL))
4820 0 : DEBUG(8, ("\"description\" not found\n"));
4821 0 : else if (!pull_utf8_talloc(mem_ctx,
4822 0 : discard_const_p(char *, &result->description),
4823 : vals[0], &converted_size))
4824 : {
4825 0 : DEBUG(0,("ldapgroup2displayentry: pull_utf8_talloc failed: %s",
4826 : strerror(errno)));
4827 : }
4828 0 : ldap_value_free(vals);
4829 :
4830 0 : if ((result->account_name == NULL) ||
4831 0 : (result->fullname == NULL) ||
4832 0 : (result->description == NULL)) {
4833 0 : DEBUG(0, ("talloc failed\n"));
4834 0 : return False;
4835 : }
4836 :
4837 0 : vals = ldap_get_values(ld, entry, "sambaSid");
4838 0 : if ((vals == NULL) || (vals[0] == NULL)) {
4839 0 : DEBUG(0, ("\"objectSid\" not found\n"));
4840 0 : if (vals != NULL) {
4841 0 : ldap_value_free(vals);
4842 : }
4843 0 : return False;
4844 : }
4845 :
4846 0 : if (!string_to_sid(&sid, vals[0])) {
4847 0 : DEBUG(0, ("Could not convert %s to SID\n", vals[0]));
4848 0 : return False;
4849 : }
4850 :
4851 0 : ldap_value_free(vals);
4852 :
4853 0 : switch (group_type) {
4854 0 : case SID_NAME_DOM_GRP:
4855 : case SID_NAME_ALIAS:
4856 :
4857 0 : if (!sid_peek_check_rid(get_global_sam_sid(), &sid, &result->rid)
4858 0 : && !sid_peek_check_rid(&global_sid_Builtin, &sid, &result->rid))
4859 : {
4860 : struct dom_sid_buf buf;
4861 0 : DEBUG(0, ("%s is not in our domain\n",
4862 : dom_sid_str_buf(&sid, &buf)));
4863 0 : return False;
4864 : }
4865 0 : break;
4866 :
4867 0 : default:
4868 0 : DEBUG(0,("unknown group type: %d\n", group_type));
4869 0 : return False;
4870 : }
4871 :
4872 0 : result->acct_flags = 0;
4873 :
4874 0 : return True;
4875 : }
4876 :
4877 0 : static bool ldapsam_search_grouptype(struct pdb_methods *methods,
4878 : struct pdb_search *search,
4879 : const struct dom_sid *sid,
4880 : enum lsa_SidType type)
4881 : {
4882 0 : struct ldapsam_privates *ldap_state =
4883 : (struct ldapsam_privates *)methods->private_data;
4884 : struct ldap_search_state *state;
4885 : struct dom_sid_buf tmp;
4886 :
4887 0 : state = talloc(search, struct ldap_search_state);
4888 0 : if (state == NULL) {
4889 0 : DEBUG(0, ("talloc failed\n"));
4890 0 : return False;
4891 : }
4892 :
4893 0 : state->connection = ldap_state->smbldap_state;
4894 :
4895 0 : state->base = lp_ldap_suffix();
4896 0 : state->connection = ldap_state->smbldap_state;
4897 0 : state->scope = LDAP_SCOPE_SUBTREE;
4898 0 : state->filter = talloc_asprintf(search, "(&(objectclass=%s)"
4899 : "(sambaGroupType=%d)(sambaSID=%s*))",
4900 : LDAP_OBJ_GROUPMAP,
4901 : type,
4902 : dom_sid_str_buf(sid, &tmp));
4903 0 : state->attrs = talloc_attrs(search, "cn", "sambaSid",
4904 : "displayName", "description",
4905 : "sambaGroupType", NULL);
4906 0 : state->attrsonly = 0;
4907 0 : state->pagedresults_cookie = NULL;
4908 0 : state->entries = NULL;
4909 0 : state->group_type = type;
4910 0 : state->ldap2displayentry = ldapgroup2displayentry;
4911 :
4912 0 : if ((state->filter == NULL) || (state->attrs == NULL)) {
4913 0 : DEBUG(0, ("talloc failed\n"));
4914 0 : return False;
4915 : }
4916 :
4917 0 : search->private_data = state;
4918 0 : search->next_entry = ldapsam_search_next_entry;
4919 0 : search->search_end = ldapsam_search_end;
4920 :
4921 0 : return ldapsam_search_firstpage(search);
4922 : }
4923 :
4924 0 : static bool ldapsam_search_groups(struct pdb_methods *methods,
4925 : struct pdb_search *search)
4926 : {
4927 0 : return ldapsam_search_grouptype(methods, search, get_global_sam_sid(), SID_NAME_DOM_GRP);
4928 : }
4929 :
4930 0 : static bool ldapsam_search_aliases(struct pdb_methods *methods,
4931 : struct pdb_search *search,
4932 : const struct dom_sid *sid)
4933 : {
4934 0 : return ldapsam_search_grouptype(methods, search, sid, SID_NAME_ALIAS);
4935 : }
4936 :
4937 0 : static uint32_t ldapsam_capabilities(struct pdb_methods *methods)
4938 : {
4939 0 : return PDB_CAP_STORE_RIDS;
4940 : }
4941 :
4942 0 : static NTSTATUS ldapsam_get_new_rid(struct ldapsam_privates *priv,
4943 : uint32_t *rid)
4944 : {
4945 0 : struct smbldap_state *smbldap_state = priv->smbldap_state;
4946 :
4947 0 : LDAPMessage *result = NULL;
4948 0 : LDAPMessage *entry = NULL;
4949 0 : LDAPMod **mods = NULL;
4950 : NTSTATUS status;
4951 : char *value;
4952 : int rc;
4953 0 : uint32_t nextRid = 0;
4954 : const char *dn;
4955 : uint32_t tmp;
4956 0 : int error = 0;
4957 :
4958 : TALLOC_CTX *mem_ctx;
4959 :
4960 0 : mem_ctx = talloc_new(NULL);
4961 0 : if (mem_ctx == NULL) {
4962 0 : DEBUG(0, ("talloc_new failed\n"));
4963 0 : return NT_STATUS_NO_MEMORY;
4964 : }
4965 :
4966 0 : status = smbldap_search_domain_info(smbldap_state, &result,
4967 : get_global_sam_name(), False);
4968 0 : if (!NT_STATUS_IS_OK(status)) {
4969 0 : DEBUG(3, ("Could not get domain info: %s\n",
4970 : nt_errstr(status)));
4971 0 : goto done;
4972 : }
4973 :
4974 0 : smbldap_talloc_autofree_ldapmsg(mem_ctx, result);
4975 :
4976 0 : entry = ldap_first_entry(priv2ld(priv), result);
4977 0 : if (entry == NULL) {
4978 0 : DEBUG(0, ("Could not get domain info entry\n"));
4979 0 : status = NT_STATUS_INTERNAL_DB_CORRUPTION;
4980 0 : goto done;
4981 : }
4982 :
4983 : /* Find the largest of the three attributes "sambaNextRid",
4984 : "sambaNextGroupRid" and "sambaNextUserRid". I gave up on the
4985 : concept of differentiating between user and group rids, and will
4986 : use only "sambaNextRid" in the future. But for compatibility
4987 : reasons I look if others have chosen different strategies -- VL */
4988 :
4989 0 : value = smbldap_talloc_single_attribute(priv2ld(priv), entry,
4990 : "sambaNextRid", mem_ctx);
4991 0 : if (value != NULL) {
4992 0 : tmp = (uint32_t)smb_strtoul(value,
4993 : NULL,
4994 : 10,
4995 : &error,
4996 : SMB_STR_STANDARD);
4997 0 : if (error != 0) {
4998 0 : goto done;
4999 : }
5000 :
5001 0 : nextRid = MAX(nextRid, tmp);
5002 : }
5003 :
5004 0 : value = smbldap_talloc_single_attribute(priv2ld(priv), entry,
5005 : "sambaNextUserRid", mem_ctx);
5006 0 : if (value != NULL) {
5007 0 : tmp = (uint32_t)smb_strtoul(value,
5008 : NULL,
5009 : 10,
5010 : &error,
5011 : SMB_STR_STANDARD);
5012 0 : if (error != 0) {
5013 0 : goto done;
5014 : }
5015 :
5016 0 : nextRid = MAX(nextRid, tmp);
5017 : }
5018 :
5019 0 : value = smbldap_talloc_single_attribute(priv2ld(priv), entry,
5020 : "sambaNextGroupRid", mem_ctx);
5021 0 : if (value != NULL) {
5022 0 : tmp = (uint32_t)smb_strtoul(value,
5023 : NULL,
5024 : 10,
5025 : &error,
5026 : SMB_STR_STANDARD);
5027 0 : if (error != 0) {
5028 0 : goto done;
5029 : }
5030 :
5031 0 : nextRid = MAX(nextRid, tmp);
5032 : }
5033 :
5034 0 : if (nextRid == 0) {
5035 0 : nextRid = BASE_RID-1;
5036 : }
5037 :
5038 0 : nextRid += 1;
5039 :
5040 0 : smbldap_make_mod(priv2ld(priv), entry, &mods, "sambaNextRid",
5041 0 : talloc_asprintf(mem_ctx, "%d", nextRid));
5042 0 : smbldap_talloc_autofree_ldapmod(mem_ctx, mods);
5043 :
5044 0 : if ((dn = smbldap_talloc_dn(mem_ctx, priv2ld(priv), entry)) == NULL) {
5045 0 : status = NT_STATUS_NO_MEMORY;
5046 0 : goto done;
5047 : }
5048 :
5049 0 : rc = smbldap_modify(smbldap_state, dn, mods);
5050 :
5051 : /* ACCESS_DENIED is used as a placeholder for "the modify failed,
5052 : * please retry" */
5053 :
5054 0 : status = (rc == LDAP_SUCCESS) ? NT_STATUS_OK : NT_STATUS_ACCESS_DENIED;
5055 :
5056 0 : done:
5057 0 : if (NT_STATUS_IS_OK(status)) {
5058 0 : *rid = nextRid;
5059 : }
5060 :
5061 0 : TALLOC_FREE(mem_ctx);
5062 0 : return status;
5063 : }
5064 :
5065 0 : static NTSTATUS ldapsam_new_rid_internal(struct pdb_methods *methods, uint32_t *rid)
5066 : {
5067 : int i;
5068 :
5069 0 : for (i=0; i<10; i++) {
5070 0 : NTSTATUS result = ldapsam_get_new_rid(
5071 0 : (struct ldapsam_privates *)methods->private_data, rid);
5072 0 : if (NT_STATUS_IS_OK(result)) {
5073 0 : return result;
5074 : }
5075 :
5076 0 : if (!NT_STATUS_EQUAL(result, NT_STATUS_ACCESS_DENIED)) {
5077 0 : return result;
5078 : }
5079 :
5080 : /* The ldap update failed (maybe a race condition), retry */
5081 : }
5082 :
5083 : /* Tried 10 times, fail. */
5084 0 : return NT_STATUS_ACCESS_DENIED;
5085 : }
5086 :
5087 0 : static bool ldapsam_new_rid(struct pdb_methods *methods, uint32_t *rid)
5088 : {
5089 0 : NTSTATUS result = ldapsam_new_rid_internal(methods, rid);
5090 0 : return NT_STATUS_IS_OK(result) ? True : False;
5091 : }
5092 :
5093 0 : static bool ldapsam_sid_to_id(struct pdb_methods *methods,
5094 : const struct dom_sid *sid,
5095 : struct unixid *id)
5096 : {
5097 0 : struct ldapsam_privates *priv =
5098 : (struct ldapsam_privates *)methods->private_data;
5099 : char *filter;
5100 0 : int error = 0;
5101 : struct dom_sid_buf buf;
5102 0 : const char *attrs[] = { "sambaGroupType", "gidNumber", "uidNumber",
5103 : NULL };
5104 0 : LDAPMessage *result = NULL;
5105 0 : LDAPMessage *entry = NULL;
5106 0 : bool ret = False;
5107 : char *value;
5108 : int rc;
5109 :
5110 : TALLOC_CTX *mem_ctx;
5111 :
5112 0 : ret = pdb_sid_to_id_unix_users_and_groups(sid, id);
5113 0 : if (ret == true) {
5114 0 : return true;
5115 : }
5116 :
5117 0 : mem_ctx = talloc_new(NULL);
5118 0 : if (mem_ctx == NULL) {
5119 0 : DEBUG(0, ("talloc_new failed\n"));
5120 0 : return False;
5121 : }
5122 :
5123 0 : filter = talloc_asprintf(mem_ctx,
5124 : "(&(sambaSid=%s)"
5125 : "(|(objectClass=%s)(objectClass=%s)))",
5126 : dom_sid_str_buf(sid, &buf),
5127 : LDAP_OBJ_GROUPMAP, LDAP_OBJ_SAMBASAMACCOUNT);
5128 0 : if (filter == NULL) {
5129 0 : DEBUG(5, ("talloc_asprintf failed\n"));
5130 0 : goto done;
5131 : }
5132 :
5133 0 : rc = smbldap_search_suffix(priv->smbldap_state, filter,
5134 : attrs, &result);
5135 0 : if (rc != LDAP_SUCCESS) {
5136 0 : goto done;
5137 : }
5138 0 : smbldap_talloc_autofree_ldapmsg(mem_ctx, result);
5139 :
5140 0 : if (ldap_count_entries(priv2ld(priv), result) != 1) {
5141 0 : DEBUG(10, ("Got %d entries, expected one\n",
5142 : ldap_count_entries(priv2ld(priv), result)));
5143 0 : goto done;
5144 : }
5145 :
5146 0 : entry = ldap_first_entry(priv2ld(priv), result);
5147 :
5148 0 : value = smbldap_talloc_single_attribute(priv2ld(priv), entry,
5149 : "sambaGroupType", mem_ctx);
5150 :
5151 0 : if (value != NULL) {
5152 : const char *gid_str;
5153 : /* It's a group */
5154 :
5155 0 : gid_str = smbldap_talloc_single_attribute(
5156 : priv2ld(priv), entry, "gidNumber", mem_ctx);
5157 0 : if (gid_str == NULL) {
5158 0 : DEBUG(1, ("%s has sambaGroupType but no gidNumber\n",
5159 : smbldap_talloc_dn(mem_ctx, priv2ld(priv),
5160 : entry)));
5161 0 : goto done;
5162 : }
5163 :
5164 0 : id->id = smb_strtoul(gid_str,
5165 : NULL,
5166 : 10,
5167 : &error,
5168 : SMB_STR_STANDARD);
5169 0 : if (error != 0) {
5170 0 : goto done;
5171 : }
5172 :
5173 0 : id->type = ID_TYPE_GID;
5174 0 : ret = True;
5175 0 : goto done;
5176 : }
5177 :
5178 : /* It must be a user */
5179 :
5180 0 : value = smbldap_talloc_single_attribute(priv2ld(priv), entry,
5181 : "uidNumber", mem_ctx);
5182 0 : if (value == NULL) {
5183 0 : DEBUG(1, ("Could not find uidNumber in %s\n",
5184 : smbldap_talloc_dn(mem_ctx, priv2ld(priv), entry)));
5185 0 : goto done;
5186 : }
5187 :
5188 0 : id->id = smb_strtoul(value, NULL, 10, &error, SMB_STR_STANDARD);
5189 0 : if (error != 0) {
5190 0 : goto done;
5191 : }
5192 :
5193 0 : id->type = ID_TYPE_UID;
5194 0 : ret = True;
5195 0 : done:
5196 0 : TALLOC_FREE(mem_ctx);
5197 0 : return ret;
5198 : }
5199 :
5200 : /**
5201 : * Find the SID for a uid.
5202 : * This is shortcut is only used if ldapsam:trusted is set to true.
5203 : */
5204 0 : static bool ldapsam_uid_to_sid(struct pdb_methods *methods, uid_t uid,
5205 : struct dom_sid *sid)
5206 : {
5207 0 : struct ldapsam_privates *priv =
5208 : (struct ldapsam_privates *)methods->private_data;
5209 : char *filter;
5210 0 : const char *attrs[] = { "sambaSID", NULL };
5211 0 : LDAPMessage *result = NULL;
5212 0 : LDAPMessage *entry = NULL;
5213 0 : bool ret = false;
5214 : char *user_sid_string;
5215 : struct dom_sid user_sid;
5216 : int rc;
5217 0 : TALLOC_CTX *tmp_ctx = talloc_stackframe();
5218 :
5219 0 : filter = talloc_asprintf(tmp_ctx,
5220 : "(&(uidNumber=%u)"
5221 : "(objectClass=%s)"
5222 : "(objectClass=%s))",
5223 : (unsigned int)uid,
5224 : LDAP_OBJ_POSIXACCOUNT,
5225 : LDAP_OBJ_SAMBASAMACCOUNT);
5226 0 : if (filter == NULL) {
5227 0 : DEBUG(3, ("talloc_asprintf failed\n"));
5228 0 : goto done;
5229 : }
5230 :
5231 0 : rc = smbldap_search_suffix(priv->smbldap_state, filter, attrs, &result);
5232 0 : if (rc != LDAP_SUCCESS) {
5233 0 : goto done;
5234 : }
5235 0 : smbldap_talloc_autofree_ldapmsg(tmp_ctx, result);
5236 :
5237 0 : if (ldap_count_entries(priv2ld(priv), result) != 1) {
5238 0 : DEBUG(3, ("ERROR: Got %d entries for uid %u, expected one\n",
5239 : ldap_count_entries(priv2ld(priv), result),
5240 : (unsigned int)uid));
5241 0 : goto done;
5242 : }
5243 :
5244 0 : entry = ldap_first_entry(priv2ld(priv), result);
5245 :
5246 0 : user_sid_string = smbldap_talloc_single_attribute(priv2ld(priv), entry,
5247 : "sambaSID", tmp_ctx);
5248 0 : if (user_sid_string == NULL) {
5249 0 : DEBUG(1, ("Could not find sambaSID in object '%s'\n",
5250 : smbldap_talloc_dn(tmp_ctx, priv2ld(priv), entry)));
5251 0 : goto done;
5252 : }
5253 :
5254 0 : if (!string_to_sid(&user_sid, user_sid_string)) {
5255 0 : DEBUG(3, ("Error calling string_to_sid for sid '%s'\n",
5256 : user_sid_string));
5257 0 : goto done;
5258 : }
5259 :
5260 0 : sid_copy(sid, &user_sid);
5261 :
5262 0 : ret = true;
5263 :
5264 0 : done:
5265 0 : TALLOC_FREE(tmp_ctx);
5266 0 : return ret;
5267 : }
5268 :
5269 : /**
5270 : * Find the SID for a gid.
5271 : * This is shortcut is only used if ldapsam:trusted is set to true.
5272 : */
5273 0 : static bool ldapsam_gid_to_sid(struct pdb_methods *methods, gid_t gid,
5274 : struct dom_sid *sid)
5275 : {
5276 0 : struct ldapsam_privates *priv =
5277 : (struct ldapsam_privates *)methods->private_data;
5278 : char *filter;
5279 0 : const char *attrs[] = { "sambaSID", NULL };
5280 0 : LDAPMessage *result = NULL;
5281 0 : LDAPMessage *entry = NULL;
5282 0 : bool ret = false;
5283 : char *group_sid_string;
5284 : struct dom_sid group_sid;
5285 : int rc;
5286 0 : TALLOC_CTX *tmp_ctx = talloc_stackframe();
5287 :
5288 0 : filter = talloc_asprintf(tmp_ctx,
5289 : "(&(gidNumber=%u)"
5290 : "(objectClass=%s))",
5291 : (unsigned int)gid,
5292 : LDAP_OBJ_GROUPMAP);
5293 0 : if (filter == NULL) {
5294 0 : DEBUG(3, ("talloc_asprintf failed\n"));
5295 0 : goto done;
5296 : }
5297 :
5298 0 : rc = smbldap_search_suffix(priv->smbldap_state, filter, attrs, &result);
5299 0 : if (rc != LDAP_SUCCESS) {
5300 0 : goto done;
5301 : }
5302 0 : smbldap_talloc_autofree_ldapmsg(tmp_ctx, result);
5303 :
5304 0 : if (ldap_count_entries(priv2ld(priv), result) != 1) {
5305 0 : DEBUG(3, ("ERROR: Got %d entries for gid %u, expected one\n",
5306 : ldap_count_entries(priv2ld(priv), result),
5307 : (unsigned int)gid));
5308 0 : goto done;
5309 : }
5310 :
5311 0 : entry = ldap_first_entry(priv2ld(priv), result);
5312 :
5313 0 : group_sid_string = smbldap_talloc_single_attribute(priv2ld(priv), entry,
5314 : "sambaSID", tmp_ctx);
5315 0 : if (group_sid_string == NULL) {
5316 0 : DEBUG(1, ("Could not find sambaSID in object '%s'\n",
5317 : smbldap_talloc_dn(tmp_ctx, priv2ld(priv), entry)));
5318 0 : goto done;
5319 : }
5320 :
5321 0 : if (!string_to_sid(&group_sid, group_sid_string)) {
5322 0 : DEBUG(3, ("Error calling string_to_sid for sid '%s'\n",
5323 : group_sid_string));
5324 0 : goto done;
5325 : }
5326 :
5327 0 : sid_copy(sid, &group_sid);
5328 :
5329 0 : ret = true;
5330 :
5331 0 : done:
5332 0 : TALLOC_FREE(tmp_ctx);
5333 0 : return ret;
5334 : }
5335 :
5336 0 : static bool ldapsam_id_to_sid(struct pdb_methods *methods, struct unixid *id,
5337 : struct dom_sid *sid)
5338 : {
5339 0 : switch (id->type) {
5340 0 : case ID_TYPE_UID:
5341 0 : return ldapsam_uid_to_sid(methods, id->id, sid);
5342 :
5343 0 : case ID_TYPE_GID:
5344 0 : return ldapsam_gid_to_sid(methods, id->id, sid);
5345 :
5346 0 : default:
5347 0 : return false;
5348 : }
5349 : }
5350 :
5351 :
5352 : /*
5353 : * The following functions are called only if
5354 : * ldapsam:trusted and ldapsam:editposix are
5355 : * set to true
5356 : */
5357 :
5358 : /*
5359 : * ldapsam_create_user creates a new
5360 : * posixAccount and sambaSamAccount object
5361 : * in the ldap users subtree
5362 : *
5363 : * The uid is allocated by winbindd.
5364 : */
5365 :
5366 0 : static NTSTATUS ldapsam_create_user(struct pdb_methods *my_methods,
5367 : TALLOC_CTX *tmp_ctx, const char *name,
5368 : uint32_t acb_info, uint32_t *rid)
5369 : {
5370 0 : struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
5371 0 : LDAPMessage *entry = NULL;
5372 0 : LDAPMessage *result = NULL;
5373 : uint32_t num_result;
5374 0 : bool is_machine = False;
5375 0 : bool add_posix = False;
5376 0 : bool init_okay = False;
5377 0 : LDAPMod **mods = NULL;
5378 : struct samu *user;
5379 : char *filter;
5380 : char *username;
5381 : char *homedir;
5382 : char *gidstr;
5383 : char *uidstr;
5384 : char *shell;
5385 0 : const char *dn = NULL;
5386 : struct dom_sid group_sid;
5387 : struct dom_sid user_sid;
5388 0 : gid_t gid = -1;
5389 0 : uid_t uid = -1;
5390 : NTSTATUS ret;
5391 : int rc;
5392 :
5393 0 : if (((acb_info & ACB_NORMAL) && name[strlen(name)-1] == '$') ||
5394 0 : acb_info & ACB_WSTRUST ||
5395 0 : acb_info & ACB_SVRTRUST ||
5396 0 : acb_info & ACB_DOMTRUST) {
5397 0 : is_machine = True;
5398 : }
5399 :
5400 0 : username = escape_ldap_string(talloc_tos(), name);
5401 0 : filter = talloc_asprintf(tmp_ctx, "(&(uid=%s)(objectClass=%s))",
5402 : username, LDAP_OBJ_POSIXACCOUNT);
5403 0 : TALLOC_FREE(username);
5404 :
5405 0 : rc = smbldap_search_suffix(ldap_state->smbldap_state, filter, NULL, &result);
5406 0 : if (rc != LDAP_SUCCESS) {
5407 0 : DEBUG(0,("ldapsam_create_user: ldap search failed!\n"));
5408 0 : return NT_STATUS_ACCESS_DENIED;
5409 : }
5410 0 : smbldap_talloc_autofree_ldapmsg(tmp_ctx, result);
5411 :
5412 0 : num_result = ldap_count_entries(priv2ld(ldap_state), result);
5413 :
5414 0 : if (num_result > 1) {
5415 0 : DEBUG (0, ("ldapsam_create_user: More than one user with name [%s] ?!\n", name));
5416 0 : return NT_STATUS_INTERNAL_DB_CORRUPTION;
5417 : }
5418 :
5419 0 : if (num_result == 1) {
5420 : char *tmp;
5421 : /* check if it is just a posix account.
5422 : * or if there is a sid attached to this entry
5423 : */
5424 :
5425 0 : entry = ldap_first_entry(priv2ld(ldap_state), result);
5426 0 : if (!entry) {
5427 0 : return NT_STATUS_UNSUCCESSFUL;
5428 : }
5429 :
5430 0 : tmp = smbldap_talloc_single_attribute(priv2ld(ldap_state), entry, "sambaSID", tmp_ctx);
5431 0 : if (tmp) {
5432 0 : DEBUG (1, ("ldapsam_create_user: The user [%s] already exist!\n", name));
5433 0 : return NT_STATUS_USER_EXISTS;
5434 : }
5435 :
5436 : /* it is just a posix account, retrieve the dn for later use */
5437 0 : dn = smbldap_talloc_dn(tmp_ctx, priv2ld(ldap_state), entry);
5438 0 : if (!dn) {
5439 0 : DEBUG(0,("ldapsam_create_user: Out of memory!\n"));
5440 0 : return NT_STATUS_NO_MEMORY;
5441 : }
5442 : }
5443 :
5444 0 : if (num_result == 0) {
5445 0 : add_posix = True;
5446 : }
5447 :
5448 : /* Create the basic samu structure and generate the mods for the ldap commit */
5449 0 : if (!NT_STATUS_IS_OK((ret = ldapsam_new_rid_internal(my_methods, rid)))) {
5450 0 : DEBUG(1, ("ldapsam_create_user: Could not allocate a new RID\n"));
5451 0 : return ret;
5452 : }
5453 :
5454 0 : sid_compose(&user_sid, get_global_sam_sid(), *rid);
5455 :
5456 0 : user = samu_new(tmp_ctx);
5457 0 : if (!user) {
5458 0 : DEBUG(1,("ldapsam_create_user: Unable to allocate user struct\n"));
5459 0 : return NT_STATUS_NO_MEMORY;
5460 : }
5461 :
5462 0 : if (!pdb_set_username(user, name, PDB_SET)) {
5463 0 : DEBUG(1,("ldapsam_create_user: Unable to fill user structs\n"));
5464 0 : return NT_STATUS_UNSUCCESSFUL;
5465 : }
5466 0 : if (!pdb_set_domain(user, get_global_sam_name(), PDB_SET)) {
5467 0 : DEBUG(1,("ldapsam_create_user: Unable to fill user structs\n"));
5468 0 : return NT_STATUS_UNSUCCESSFUL;
5469 : }
5470 0 : if (is_machine) {
5471 0 : if (acb_info & ACB_NORMAL) {
5472 0 : if (!pdb_set_acct_ctrl(user, ACB_WSTRUST, PDB_SET)) {
5473 0 : DEBUG(1,("ldapsam_create_user: Unable to fill user structs\n"));
5474 0 : return NT_STATUS_UNSUCCESSFUL;
5475 : }
5476 : } else {
5477 0 : if (!pdb_set_acct_ctrl(user, acb_info, PDB_SET)) {
5478 0 : DEBUG(1,("ldapsam_create_user: Unable to fill user structs\n"));
5479 0 : return NT_STATUS_UNSUCCESSFUL;
5480 : }
5481 : }
5482 : } else {
5483 0 : if (!pdb_set_acct_ctrl(user, ACB_NORMAL | ACB_DISABLED, PDB_SET)) {
5484 0 : DEBUG(1,("ldapsam_create_user: Unable to fill user structs\n"));
5485 0 : return NT_STATUS_UNSUCCESSFUL;
5486 : }
5487 : }
5488 :
5489 0 : if (!pdb_set_user_sid(user, &user_sid, PDB_SET)) {
5490 0 : DEBUG(1,("ldapsam_create_user: Unable to fill user structs\n"));
5491 0 : return NT_STATUS_UNSUCCESSFUL;
5492 : }
5493 :
5494 0 : init_okay = init_ldap_from_sam(ldap_state, entry, &mods, user, pdb_element_is_set_or_changed);
5495 :
5496 0 : if (!init_okay) {
5497 0 : DEBUG(1,("ldapsam_create_user: Unable to fill user structs\n"));
5498 0 : ldap_mods_free(mods, true);
5499 0 : return NT_STATUS_UNSUCCESSFUL;
5500 : }
5501 :
5502 0 : if (ldap_state->schema_ver != SCHEMAVER_SAMBASAMACCOUNT) {
5503 0 : DEBUG(1,("ldapsam_create_user: Unsupported schema version\n"));
5504 : }
5505 0 : smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectClass", LDAP_OBJ_SAMBASAMACCOUNT);
5506 :
5507 0 : if (add_posix) {
5508 : char *escape_name;
5509 :
5510 0 : DEBUG(3,("ldapsam_create_user: Creating new posix user\n"));
5511 :
5512 : /* retrieve the Domain Users group gid */
5513 0 : if (!sid_compose(&group_sid, get_global_sam_sid(), DOMAIN_RID_USERS) ||
5514 0 : !sid_to_gid(&group_sid, &gid)) {
5515 0 : DEBUG (0, ("ldapsam_create_user: Unable to get the Domain Users gid: bailing out!\n"));
5516 0 : ldap_mods_free(mods, true);
5517 0 : return NT_STATUS_INVALID_PRIMARY_GROUP;
5518 : }
5519 :
5520 : /* lets allocate a new userid for this user */
5521 0 : if (!winbind_allocate_uid(&uid)) {
5522 0 : DEBUG (0, ("ldapsam_create_user: Unable to allocate a new user id: bailing out!\n"));
5523 0 : ldap_mods_free(mods, true);
5524 0 : return NT_STATUS_UNSUCCESSFUL;
5525 : }
5526 :
5527 :
5528 0 : if (is_machine) {
5529 : /* TODO: choose a more appropriate default for machines */
5530 0 : homedir = talloc_sub_specified(tmp_ctx,
5531 : lp_template_homedir(),
5532 : "SMB_workstations_home",
5533 : NULL,
5534 : ldap_state->domain_name,
5535 : uid,
5536 : gid);
5537 0 : shell = talloc_strdup(tmp_ctx, "/bin/false");
5538 : } else {
5539 0 : homedir = talloc_sub_specified(tmp_ctx,
5540 : lp_template_homedir(),
5541 : name,
5542 : NULL,
5543 : ldap_state->domain_name,
5544 : uid,
5545 : gid);
5546 0 : shell = talloc_sub_specified(tmp_ctx,
5547 : lp_template_shell(),
5548 : name,
5549 : NULL,
5550 : ldap_state->domain_name,
5551 : uid,
5552 : gid);
5553 : }
5554 0 : uidstr = talloc_asprintf(tmp_ctx, "%u", (unsigned int)uid);
5555 0 : gidstr = talloc_asprintf(tmp_ctx, "%u", (unsigned int)gid);
5556 :
5557 0 : escape_name = escape_rdn_val_string_alloc(name);
5558 0 : if (!escape_name) {
5559 0 : DEBUG (0, ("ldapsam_create_user: Out of memory!\n"));
5560 0 : ldap_mods_free(mods, true);
5561 0 : return NT_STATUS_NO_MEMORY;
5562 : }
5563 :
5564 0 : if (is_machine) {
5565 0 : dn = talloc_asprintf(tmp_ctx, "uid=%s,%s", escape_name, lp_ldap_machine_suffix (talloc_tos()));
5566 : } else {
5567 0 : dn = talloc_asprintf(tmp_ctx, "uid=%s,%s", escape_name, lp_ldap_user_suffix (talloc_tos()));
5568 : }
5569 :
5570 0 : SAFE_FREE(escape_name);
5571 :
5572 0 : if (!homedir || !shell || !uidstr || !gidstr || !dn) {
5573 0 : DEBUG (0, ("ldapsam_create_user: Out of memory!\n"));
5574 0 : ldap_mods_free(mods, true);
5575 0 : return NT_STATUS_NO_MEMORY;
5576 : }
5577 :
5578 0 : smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectClass", LDAP_OBJ_ACCOUNT);
5579 0 : smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectClass", LDAP_OBJ_POSIXACCOUNT);
5580 0 : smbldap_set_mod(&mods, LDAP_MOD_ADD, "cn", name);
5581 0 : smbldap_set_mod(&mods, LDAP_MOD_ADD, "uidNumber", uidstr);
5582 0 : smbldap_set_mod(&mods, LDAP_MOD_ADD, "gidNumber", gidstr);
5583 0 : smbldap_set_mod(&mods, LDAP_MOD_ADD, "homeDirectory", homedir);
5584 0 : smbldap_set_mod(&mods, LDAP_MOD_ADD, "loginShell", shell);
5585 : }
5586 :
5587 0 : if (add_posix) {
5588 0 : rc = smbldap_add(ldap_state->smbldap_state, dn, mods);
5589 : } else {
5590 0 : rc = smbldap_modify(ldap_state->smbldap_state, dn, mods);
5591 : }
5592 :
5593 0 : ldap_mods_free(mods, true);
5594 :
5595 0 : if (rc != LDAP_SUCCESS) {
5596 0 : DEBUG(0,("ldapsam_create_user: failed to create a new user [%s] (dn = %s)\n", name ,dn));
5597 0 : return NT_STATUS_UNSUCCESSFUL;
5598 : }
5599 :
5600 0 : DEBUG(2,("ldapsam_create_user: added account [%s] in the LDAP database\n", name));
5601 :
5602 0 : flush_pwnam_cache();
5603 :
5604 0 : return NT_STATUS_OK;
5605 : }
5606 :
5607 0 : static NTSTATUS ldapsam_delete_user(struct pdb_methods *my_methods, TALLOC_CTX *tmp_ctx, struct samu *sam_acct)
5608 : {
5609 0 : struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
5610 0 : LDAPMessage *result = NULL;
5611 0 : LDAPMessage *entry = NULL;
5612 : int num_result;
5613 : const char *dn;
5614 : char *filter;
5615 : int rc;
5616 :
5617 0 : DEBUG(0,("ldapsam_delete_user: Attempt to delete user [%s]\n", pdb_get_username(sam_acct)));
5618 :
5619 0 : filter = talloc_asprintf(tmp_ctx,
5620 : "(&(uid=%s)"
5621 : "(objectClass=%s)"
5622 : "(objectClass=%s))",
5623 : pdb_get_username(sam_acct),
5624 : LDAP_OBJ_POSIXACCOUNT,
5625 : LDAP_OBJ_SAMBASAMACCOUNT);
5626 0 : if (filter == NULL) {
5627 0 : return NT_STATUS_NO_MEMORY;
5628 : }
5629 :
5630 0 : rc = smbldap_search_suffix(ldap_state->smbldap_state, filter, NULL, &result);
5631 0 : if (rc != LDAP_SUCCESS) {
5632 0 : DEBUG(0,("ldapsam_delete_user: user search failed!\n"));
5633 0 : return NT_STATUS_UNSUCCESSFUL;
5634 : }
5635 0 : smbldap_talloc_autofree_ldapmsg(tmp_ctx, result);
5636 :
5637 0 : num_result = ldap_count_entries(priv2ld(ldap_state), result);
5638 :
5639 0 : if (num_result == 0) {
5640 0 : DEBUG(0,("ldapsam_delete_user: user not found!\n"));
5641 0 : return NT_STATUS_NO_SUCH_USER;
5642 : }
5643 :
5644 0 : if (num_result > 1) {
5645 0 : DEBUG (0, ("ldapsam_delete_user: More than one user with name [%s] ?!\n", pdb_get_username(sam_acct)));
5646 0 : return NT_STATUS_INTERNAL_DB_CORRUPTION;
5647 : }
5648 :
5649 0 : entry = ldap_first_entry(priv2ld(ldap_state), result);
5650 0 : if (!entry) {
5651 0 : return NT_STATUS_UNSUCCESSFUL;
5652 : }
5653 :
5654 : /* it is just a posix account, retrieve the dn for later use */
5655 0 : dn = smbldap_talloc_dn(tmp_ctx, priv2ld(ldap_state), entry);
5656 0 : if (!dn) {
5657 0 : DEBUG(0,("ldapsam_delete_user: Out of memory!\n"));
5658 0 : return NT_STATUS_NO_MEMORY;
5659 : }
5660 :
5661 : /* try to remove memberships first */
5662 : {
5663 : NTSTATUS status;
5664 0 : struct dom_sid *sids = NULL;
5665 0 : gid_t *gids = NULL;
5666 0 : uint32_t num_groups = 0;
5667 : int i;
5668 0 : uint32_t user_rid = pdb_get_user_rid(sam_acct);
5669 :
5670 0 : status = ldapsam_enum_group_memberships(my_methods,
5671 : tmp_ctx,
5672 : sam_acct,
5673 : &sids,
5674 : &gids,
5675 : &num_groups);
5676 0 : if (!NT_STATUS_IS_OK(status)) {
5677 0 : goto delete_dn;
5678 : }
5679 :
5680 0 : for (i=0; i < num_groups; i++) {
5681 :
5682 : uint32_t group_rid;
5683 :
5684 0 : sid_peek_rid(&sids[i], &group_rid);
5685 :
5686 0 : ldapsam_del_groupmem(my_methods,
5687 : tmp_ctx,
5688 : group_rid,
5689 : user_rid);
5690 : }
5691 : }
5692 :
5693 0 : delete_dn:
5694 :
5695 0 : rc = smbldap_delete(ldap_state->smbldap_state, dn);
5696 0 : if (rc != LDAP_SUCCESS) {
5697 0 : return NT_STATUS_UNSUCCESSFUL;
5698 : }
5699 :
5700 0 : flush_pwnam_cache();
5701 :
5702 0 : return NT_STATUS_OK;
5703 : }
5704 :
5705 : /*
5706 : * ldapsam_create_group creates a new
5707 : * posixGroup and sambaGroupMapping object
5708 : * in the ldap groups subtree
5709 : *
5710 : * The gid is allocated by winbindd.
5711 : */
5712 :
5713 0 : static NTSTATUS ldapsam_create_dom_group(struct pdb_methods *my_methods,
5714 : TALLOC_CTX *tmp_ctx,
5715 : const char *name,
5716 : uint32_t *rid)
5717 : {
5718 0 : struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
5719 : NTSTATUS ret;
5720 0 : LDAPMessage *entry = NULL;
5721 0 : LDAPMessage *result = NULL;
5722 : uint32_t num_result;
5723 0 : bool is_new_entry = False;
5724 0 : LDAPMod **mods = NULL;
5725 : char *filter;
5726 : char *groupname;
5727 : char *grouptype;
5728 : char *gidstr;
5729 0 : const char *dn = NULL;
5730 : struct dom_sid group_sid;
5731 : struct dom_sid_buf buf;
5732 0 : gid_t gid = -1;
5733 : int rc;
5734 0 : int error = 0;
5735 :
5736 0 : groupname = escape_ldap_string(talloc_tos(), name);
5737 0 : filter = talloc_asprintf(tmp_ctx, "(&(cn=%s)(objectClass=%s))",
5738 : groupname, LDAP_OBJ_POSIXGROUP);
5739 0 : TALLOC_FREE(groupname);
5740 :
5741 0 : rc = smbldap_search_suffix(ldap_state->smbldap_state, filter, NULL, &result);
5742 0 : if (rc != LDAP_SUCCESS) {
5743 0 : DEBUG(0,("ldapsam_create_group: ldap search failed!\n"));
5744 0 : return NT_STATUS_UNSUCCESSFUL;
5745 : }
5746 0 : smbldap_talloc_autofree_ldapmsg(tmp_ctx, result);
5747 :
5748 0 : num_result = ldap_count_entries(priv2ld(ldap_state), result);
5749 :
5750 0 : if (num_result > 1) {
5751 0 : DEBUG (0, ("ldapsam_create_group: There exists more than one group with name [%s]: bailing out!\n", name));
5752 0 : return NT_STATUS_INTERNAL_DB_CORRUPTION;
5753 : }
5754 :
5755 0 : if (num_result == 1) {
5756 : char *tmp;
5757 : /* check if it is just a posix group.
5758 : * or if there is a sid attached to this entry
5759 : */
5760 :
5761 0 : entry = ldap_first_entry(priv2ld(ldap_state), result);
5762 0 : if (!entry) {
5763 0 : return NT_STATUS_UNSUCCESSFUL;
5764 : }
5765 :
5766 0 : tmp = smbldap_talloc_single_attribute(priv2ld(ldap_state), entry, "sambaSID", tmp_ctx);
5767 0 : if (tmp) {
5768 0 : DEBUG (1, ("ldapsam_create_group: The group [%s] already exist!\n", name));
5769 0 : return NT_STATUS_GROUP_EXISTS;
5770 : }
5771 :
5772 : /* it is just a posix group, retrieve the gid and the dn for later use */
5773 0 : tmp = smbldap_talloc_single_attribute(priv2ld(ldap_state), entry, "gidNumber", tmp_ctx);
5774 0 : if (!tmp) {
5775 0 : DEBUG (1, ("ldapsam_create_group: Couldn't retrieve the gidNumber for [%s]?!?!\n", name));
5776 0 : return NT_STATUS_INTERNAL_DB_CORRUPTION;
5777 : }
5778 :
5779 0 : gid = smb_strtoul(tmp, NULL, 10, &error, SMB_STR_STANDARD);
5780 0 : if (error != 0) {
5781 0 : DBG_ERR("Failed to convert gidNumber\n");
5782 0 : return NT_STATUS_UNSUCCESSFUL;
5783 : }
5784 :
5785 0 : dn = smbldap_talloc_dn(tmp_ctx, priv2ld(ldap_state), entry);
5786 0 : if (!dn) {
5787 0 : DEBUG(0,("ldapsam_create_group: Out of memory!\n"));
5788 0 : return NT_STATUS_NO_MEMORY;
5789 : }
5790 : }
5791 :
5792 0 : if (num_result == 0) {
5793 0 : is_new_entry = true;
5794 : }
5795 :
5796 0 : if (!NT_STATUS_IS_OK((ret = ldapsam_new_rid_internal(my_methods, rid)))) {
5797 0 : DEBUG(1, ("ldapsam_create_group: Could not allocate a new RID\n"));
5798 0 : return ret;
5799 : }
5800 :
5801 0 : sid_compose(&group_sid, get_global_sam_sid(), *rid);
5802 :
5803 0 : grouptype = talloc_asprintf(tmp_ctx, "%d", SID_NAME_DOM_GRP);
5804 :
5805 0 : if (!grouptype) {
5806 0 : DEBUG(0,("ldapsam_create_group: Out of memory!\n"));
5807 0 : return NT_STATUS_NO_MEMORY;
5808 : }
5809 :
5810 0 : smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectClass", LDAP_OBJ_GROUPMAP);
5811 0 : smbldap_set_mod(&mods,
5812 : LDAP_MOD_ADD,
5813 : "sambaSid",
5814 0 : dom_sid_str_buf(&group_sid, &buf));
5815 0 : smbldap_set_mod(&mods, LDAP_MOD_ADD, "sambaGroupType", grouptype);
5816 0 : smbldap_set_mod(&mods, LDAP_MOD_ADD, "displayName", name);
5817 :
5818 0 : if (is_new_entry) {
5819 : char *escape_name;
5820 :
5821 0 : DEBUG(3,("ldapsam_create_user: Creating new posix group\n"));
5822 :
5823 : /* lets allocate a new groupid for this group */
5824 0 : if (!winbind_allocate_gid(&gid)) {
5825 0 : DEBUG (0, ("ldapsam_create_group: Unable to allocate a new group id: bailing out!\n"));
5826 0 : return NT_STATUS_UNSUCCESSFUL;
5827 : }
5828 :
5829 0 : gidstr = talloc_asprintf(tmp_ctx, "%u", (unsigned int)gid);
5830 :
5831 0 : escape_name = escape_rdn_val_string_alloc(name);
5832 0 : if (!escape_name) {
5833 0 : DEBUG (0, ("ldapsam_create_group: Out of memory!\n"));
5834 0 : return NT_STATUS_NO_MEMORY;
5835 : }
5836 :
5837 0 : dn = talloc_asprintf(tmp_ctx, "cn=%s,%s", escape_name, lp_ldap_group_suffix(talloc_tos()));
5838 :
5839 0 : SAFE_FREE(escape_name);
5840 :
5841 0 : if (!gidstr || !dn) {
5842 0 : DEBUG (0, ("ldapsam_create_group: Out of memory!\n"));
5843 0 : return NT_STATUS_NO_MEMORY;
5844 : }
5845 :
5846 0 : smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectclass", LDAP_OBJ_POSIXGROUP);
5847 0 : smbldap_set_mod(&mods, LDAP_MOD_ADD, "cn", name);
5848 0 : smbldap_set_mod(&mods, LDAP_MOD_ADD, "gidNumber", gidstr);
5849 : }
5850 :
5851 0 : smbldap_talloc_autofree_ldapmod(tmp_ctx, mods);
5852 :
5853 0 : if (is_new_entry) {
5854 0 : rc = smbldap_add(ldap_state->smbldap_state, dn, mods);
5855 : #if 0
5856 : if (rc == LDAP_OBJECT_CLASS_VIOLATION) {
5857 : /* This call may fail with rfc2307bis schema */
5858 : /* Retry adding a structural class */
5859 : smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectClass", "????");
5860 : rc = smbldap_add(ldap_state->smbldap_state, dn, mods);
5861 : }
5862 : #endif
5863 : } else {
5864 0 : rc = smbldap_modify(ldap_state->smbldap_state, dn, mods);
5865 : }
5866 :
5867 0 : if (rc != LDAP_SUCCESS) {
5868 0 : DEBUG(0,("ldapsam_create_group: failed to create a new group [%s] (dn = %s)\n", name ,dn));
5869 0 : return NT_STATUS_UNSUCCESSFUL;
5870 : }
5871 :
5872 0 : DEBUG(2,("ldapsam_create_group: added group [%s] in the LDAP database\n", name));
5873 :
5874 0 : return NT_STATUS_OK;
5875 : }
5876 :
5877 0 : static NTSTATUS ldapsam_delete_dom_group(struct pdb_methods *my_methods, TALLOC_CTX *tmp_ctx, uint32_t rid)
5878 : {
5879 0 : struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
5880 0 : LDAPMessage *result = NULL;
5881 0 : LDAPMessage *entry = NULL;
5882 : int num_result;
5883 : const char *dn;
5884 : char *gidstr;
5885 : char *filter;
5886 : struct dom_sid group_sid;
5887 : struct dom_sid_buf buf;
5888 : int rc;
5889 :
5890 : /* get the group sid */
5891 0 : sid_compose(&group_sid, get_global_sam_sid(), rid);
5892 :
5893 0 : filter = talloc_asprintf(tmp_ctx,
5894 : "(&(sambaSID=%s)"
5895 : "(objectClass=%s)"
5896 : "(objectClass=%s))",
5897 : dom_sid_str_buf(&group_sid, &buf),
5898 : LDAP_OBJ_POSIXGROUP,
5899 : LDAP_OBJ_GROUPMAP);
5900 0 : if (filter == NULL) {
5901 0 : return NT_STATUS_NO_MEMORY;
5902 : }
5903 :
5904 0 : rc = smbldap_search_suffix(ldap_state->smbldap_state, filter, NULL, &result);
5905 0 : if (rc != LDAP_SUCCESS) {
5906 0 : DEBUG(1,("ldapsam_delete_dom_group: group search failed!\n"));
5907 0 : return NT_STATUS_UNSUCCESSFUL;
5908 : }
5909 0 : smbldap_talloc_autofree_ldapmsg(tmp_ctx, result);
5910 :
5911 0 : num_result = ldap_count_entries(priv2ld(ldap_state), result);
5912 :
5913 0 : if (num_result == 0) {
5914 0 : DEBUG(1,("ldapsam_delete_dom_group: group not found!\n"));
5915 0 : return NT_STATUS_NO_SUCH_GROUP;
5916 : }
5917 :
5918 0 : if (num_result > 1) {
5919 0 : DEBUG (0, ("ldapsam_delete_dom_group: More than one group with the same SID ?!\n"));
5920 0 : return NT_STATUS_INTERNAL_DB_CORRUPTION;
5921 : }
5922 :
5923 0 : entry = ldap_first_entry(priv2ld(ldap_state), result);
5924 0 : if (!entry) {
5925 0 : return NT_STATUS_UNSUCCESSFUL;
5926 : }
5927 :
5928 : /* here it is, retrieve the dn for later use */
5929 0 : dn = smbldap_talloc_dn(tmp_ctx, priv2ld(ldap_state), entry);
5930 0 : if (!dn) {
5931 0 : DEBUG(0,("ldapsam_delete_dom_group: Out of memory!\n"));
5932 0 : return NT_STATUS_NO_MEMORY;
5933 : }
5934 :
5935 0 : gidstr = smbldap_talloc_single_attribute(priv2ld(ldap_state), entry, "gidNumber", tmp_ctx);
5936 0 : if (!gidstr) {
5937 0 : DEBUG (0, ("ldapsam_delete_dom_group: Unable to find the group's gid!\n"));
5938 0 : return NT_STATUS_INTERNAL_DB_CORRUPTION;
5939 : }
5940 :
5941 : /* check no user have this group marked as primary group */
5942 0 : filter = talloc_asprintf(tmp_ctx,
5943 : "(&(gidNumber=%s)"
5944 : "(objectClass=%s)"
5945 : "(objectClass=%s))",
5946 : gidstr,
5947 : LDAP_OBJ_POSIXACCOUNT,
5948 : LDAP_OBJ_SAMBASAMACCOUNT);
5949 :
5950 0 : rc = smbldap_search_suffix(ldap_state->smbldap_state, filter, NULL, &result);
5951 0 : if (rc != LDAP_SUCCESS) {
5952 0 : DEBUG(1,("ldapsam_delete_dom_group: accounts search failed!\n"));
5953 0 : return NT_STATUS_UNSUCCESSFUL;
5954 : }
5955 0 : smbldap_talloc_autofree_ldapmsg(tmp_ctx, result);
5956 :
5957 0 : num_result = ldap_count_entries(priv2ld(ldap_state), result);
5958 :
5959 0 : if (num_result != 0) {
5960 0 : DEBUG(3,("ldapsam_delete_dom_group: Can't delete group, it is a primary group for %d users\n", num_result));
5961 0 : return NT_STATUS_MEMBERS_PRIMARY_GROUP;
5962 : }
5963 :
5964 0 : rc = smbldap_delete(ldap_state->smbldap_state, dn);
5965 0 : if (rc != LDAP_SUCCESS) {
5966 0 : return NT_STATUS_UNSUCCESSFUL;
5967 : }
5968 :
5969 0 : return NT_STATUS_OK;
5970 : }
5971 :
5972 0 : static NTSTATUS ldapsam_change_groupmem(struct pdb_methods *my_methods,
5973 : TALLOC_CTX *tmp_ctx,
5974 : uint32_t group_rid,
5975 : uint32_t member_rid,
5976 : int modop)
5977 : {
5978 0 : struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
5979 0 : LDAPMessage *entry = NULL;
5980 0 : LDAPMessage *result = NULL;
5981 : uint32_t num_result;
5982 0 : LDAPMod **mods = NULL;
5983 : char *filter;
5984 : char *uidstr;
5985 0 : const char *dn = NULL;
5986 : struct dom_sid group_sid;
5987 : struct dom_sid member_sid;
5988 : struct dom_sid_buf buf;
5989 : int rc;
5990 0 : int error = 0;
5991 :
5992 0 : switch (modop) {
5993 0 : case LDAP_MOD_ADD:
5994 0 : DEBUG(1,("ldapsam_change_groupmem: add new member(rid=%d) to a domain group(rid=%d)", member_rid, group_rid));
5995 0 : break;
5996 0 : case LDAP_MOD_DELETE:
5997 0 : DEBUG(1,("ldapsam_change_groupmem: delete member(rid=%d) from a domain group(rid=%d)", member_rid, group_rid));
5998 0 : break;
5999 0 : default:
6000 0 : return NT_STATUS_UNSUCCESSFUL;
6001 : }
6002 :
6003 : /* get member sid */
6004 0 : sid_compose(&member_sid, get_global_sam_sid(), member_rid);
6005 :
6006 : /* get the group sid */
6007 0 : sid_compose(&group_sid, get_global_sam_sid(), group_rid);
6008 :
6009 0 : filter = talloc_asprintf(tmp_ctx,
6010 : "(&(sambaSID=%s)"
6011 : "(objectClass=%s)"
6012 : "(objectClass=%s))",
6013 : dom_sid_str_buf(&member_sid, &buf),
6014 : LDAP_OBJ_POSIXACCOUNT,
6015 : LDAP_OBJ_SAMBASAMACCOUNT);
6016 0 : if (filter == NULL) {
6017 0 : return NT_STATUS_NO_MEMORY;
6018 : }
6019 :
6020 : /* get the member uid */
6021 0 : rc = smbldap_search_suffix(ldap_state->smbldap_state, filter, NULL, &result);
6022 0 : if (rc != LDAP_SUCCESS) {
6023 0 : DEBUG(1,("ldapsam_change_groupmem: member search failed!\n"));
6024 0 : return NT_STATUS_UNSUCCESSFUL;
6025 : }
6026 0 : smbldap_talloc_autofree_ldapmsg(tmp_ctx, result);
6027 :
6028 0 : num_result = ldap_count_entries(priv2ld(ldap_state), result);
6029 :
6030 0 : if (num_result == 0) {
6031 0 : DEBUG(1,("ldapsam_change_groupmem: member not found!\n"));
6032 0 : return NT_STATUS_NO_SUCH_MEMBER;
6033 : }
6034 :
6035 0 : if (num_result > 1) {
6036 0 : DEBUG (0, ("ldapsam_change_groupmem: More than one account with the same SID ?!\n"));
6037 0 : return NT_STATUS_INTERNAL_DB_CORRUPTION;
6038 : }
6039 :
6040 0 : entry = ldap_first_entry(priv2ld(ldap_state), result);
6041 0 : if (!entry) {
6042 0 : return NT_STATUS_UNSUCCESSFUL;
6043 : }
6044 :
6045 0 : if (modop == LDAP_MOD_DELETE) {
6046 : /* check if we are trying to remove the member from his primary group */
6047 : char *gidstr;
6048 : gid_t user_gid, group_gid;
6049 :
6050 0 : gidstr = smbldap_talloc_single_attribute(priv2ld(ldap_state), entry, "gidNumber", tmp_ctx);
6051 0 : if (!gidstr) {
6052 0 : DEBUG (0, ("ldapsam_change_groupmem: Unable to find the member's gid!\n"));
6053 0 : return NT_STATUS_INTERNAL_DB_CORRUPTION;
6054 : }
6055 :
6056 0 : user_gid = smb_strtoul(gidstr, NULL, 10, &error, SMB_STR_STANDARD);
6057 0 : if (error != 0) {
6058 0 : DBG_ERR("Failed to convert user gid\n");
6059 0 : return NT_STATUS_UNSUCCESSFUL;
6060 : }
6061 :
6062 0 : if (!sid_to_gid(&group_sid, &group_gid)) {
6063 0 : DEBUG (0, ("ldapsam_change_groupmem: Unable to get group gid from SID!\n"));
6064 0 : return NT_STATUS_UNSUCCESSFUL;
6065 : }
6066 :
6067 0 : if (user_gid == group_gid) {
6068 0 : DEBUG (3, ("ldapsam_change_groupmem: can't remove user from its own primary group!\n"));
6069 0 : return NT_STATUS_MEMBERS_PRIMARY_GROUP;
6070 : }
6071 : }
6072 :
6073 : /* here it is, retrieve the uid for later use */
6074 0 : uidstr = smbldap_talloc_single_attribute(priv2ld(ldap_state), entry, "uid", tmp_ctx);
6075 0 : if (!uidstr) {
6076 0 : DEBUG (0, ("ldapsam_change_groupmem: Unable to find the member's name!\n"));
6077 0 : return NT_STATUS_INTERNAL_DB_CORRUPTION;
6078 : }
6079 :
6080 0 : filter = talloc_asprintf(tmp_ctx,
6081 : "(&(sambaSID=%s)"
6082 : "(objectClass=%s)"
6083 : "(objectClass=%s))",
6084 : dom_sid_str_buf(&group_sid, &buf),
6085 : LDAP_OBJ_POSIXGROUP,
6086 : LDAP_OBJ_GROUPMAP);
6087 :
6088 : /* get the group */
6089 0 : rc = smbldap_search_suffix(ldap_state->smbldap_state, filter, NULL, &result);
6090 0 : if (rc != LDAP_SUCCESS) {
6091 0 : DEBUG(1,("ldapsam_change_groupmem: group search failed!\n"));
6092 0 : return NT_STATUS_UNSUCCESSFUL;
6093 : }
6094 0 : smbldap_talloc_autofree_ldapmsg(tmp_ctx, result);
6095 :
6096 0 : num_result = ldap_count_entries(priv2ld(ldap_state), result);
6097 :
6098 0 : if (num_result == 0) {
6099 0 : DEBUG(1,("ldapsam_change_groupmem: group not found!\n"));
6100 0 : return NT_STATUS_NO_SUCH_GROUP;
6101 : }
6102 :
6103 0 : if (num_result > 1) {
6104 0 : DEBUG (0, ("ldapsam_change_groupmem: More than one group with the same SID ?!\n"));
6105 0 : return NT_STATUS_INTERNAL_DB_CORRUPTION;
6106 : }
6107 :
6108 0 : entry = ldap_first_entry(priv2ld(ldap_state), result);
6109 0 : if (!entry) {
6110 0 : return NT_STATUS_UNSUCCESSFUL;
6111 : }
6112 :
6113 : /* here it is, retrieve the dn for later use */
6114 0 : dn = smbldap_talloc_dn(tmp_ctx, priv2ld(ldap_state), entry);
6115 0 : if (!dn) {
6116 0 : DEBUG(0,("ldapsam_change_groupmem: Out of memory!\n"));
6117 0 : return NT_STATUS_NO_MEMORY;
6118 : }
6119 :
6120 0 : smbldap_set_mod(&mods, modop, "memberUid", uidstr);
6121 :
6122 0 : smbldap_talloc_autofree_ldapmod(tmp_ctx, mods);
6123 :
6124 0 : rc = smbldap_modify(ldap_state->smbldap_state, dn, mods);
6125 0 : if (rc != LDAP_SUCCESS) {
6126 0 : if (rc == LDAP_TYPE_OR_VALUE_EXISTS && modop == LDAP_MOD_ADD) {
6127 0 : DEBUG(1,("ldapsam_change_groupmem: member is already in group, add failed!\n"));
6128 0 : return NT_STATUS_MEMBER_IN_GROUP;
6129 : }
6130 0 : if (rc == LDAP_NO_SUCH_ATTRIBUTE && modop == LDAP_MOD_DELETE) {
6131 0 : DEBUG(1,("ldapsam_change_groupmem: member is not in group, delete failed!\n"));
6132 0 : return NT_STATUS_MEMBER_NOT_IN_GROUP;
6133 : }
6134 0 : return NT_STATUS_UNSUCCESSFUL;
6135 : }
6136 :
6137 0 : return NT_STATUS_OK;
6138 : }
6139 :
6140 0 : static NTSTATUS ldapsam_add_groupmem(struct pdb_methods *my_methods,
6141 : TALLOC_CTX *tmp_ctx,
6142 : uint32_t group_rid,
6143 : uint32_t member_rid)
6144 : {
6145 0 : return ldapsam_change_groupmem(my_methods, tmp_ctx, group_rid, member_rid, LDAP_MOD_ADD);
6146 : }
6147 0 : static NTSTATUS ldapsam_del_groupmem(struct pdb_methods *my_methods,
6148 : TALLOC_CTX *tmp_ctx,
6149 : uint32_t group_rid,
6150 : uint32_t member_rid)
6151 : {
6152 0 : return ldapsam_change_groupmem(my_methods, tmp_ctx, group_rid, member_rid, LDAP_MOD_DELETE);
6153 : }
6154 :
6155 0 : static NTSTATUS ldapsam_set_primary_group(struct pdb_methods *my_methods,
6156 : TALLOC_CTX *mem_ctx,
6157 : struct samu *sampass)
6158 : {
6159 0 : struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
6160 0 : LDAPMessage *entry = NULL;
6161 0 : LDAPMessage *result = NULL;
6162 : uint32_t num_result;
6163 0 : LDAPMod **mods = NULL;
6164 : char *filter;
6165 : char *escape_username;
6166 : char *gidstr;
6167 0 : char *dn = NULL;
6168 : gid_t gid;
6169 : int rc;
6170 :
6171 0 : DEBUG(0,("ldapsam_set_primary_group: Attempt to set primary group for user [%s]\n", pdb_get_username(sampass)));
6172 :
6173 0 : if (!sid_to_gid(pdb_get_group_sid(sampass), &gid)) {
6174 0 : DEBUG(0,("ldapsam_set_primary_group: failed to retrieve gid from user's group SID!\n"));
6175 0 : return NT_STATUS_UNSUCCESSFUL;
6176 : }
6177 0 : gidstr = talloc_asprintf(mem_ctx, "%u", (unsigned int)gid);
6178 0 : if (!gidstr) {
6179 0 : DEBUG(0,("ldapsam_set_primary_group: Out of Memory!\n"));
6180 0 : return NT_STATUS_NO_MEMORY;
6181 : }
6182 :
6183 0 : escape_username = escape_ldap_string(talloc_tos(),
6184 : pdb_get_username(sampass));
6185 0 : if (escape_username== NULL) {
6186 0 : return NT_STATUS_NO_MEMORY;
6187 : }
6188 :
6189 0 : filter = talloc_asprintf(mem_ctx,
6190 : "(&(uid=%s)"
6191 : "(objectClass=%s)"
6192 : "(objectClass=%s))",
6193 : escape_username,
6194 : LDAP_OBJ_POSIXACCOUNT,
6195 : LDAP_OBJ_SAMBASAMACCOUNT);
6196 :
6197 0 : TALLOC_FREE(escape_username);
6198 :
6199 0 : if (filter == NULL) {
6200 0 : return NT_STATUS_NO_MEMORY;
6201 : }
6202 :
6203 0 : rc = smbldap_search_suffix(ldap_state->smbldap_state, filter, NULL, &result);
6204 0 : if (rc != LDAP_SUCCESS) {
6205 0 : DEBUG(0,("ldapsam_set_primary_group: user search failed!\n"));
6206 0 : return NT_STATUS_UNSUCCESSFUL;
6207 : }
6208 0 : smbldap_talloc_autofree_ldapmsg(mem_ctx, result);
6209 :
6210 0 : num_result = ldap_count_entries(priv2ld(ldap_state), result);
6211 :
6212 0 : if (num_result == 0) {
6213 0 : DEBUG(0,("ldapsam_set_primary_group: user not found!\n"));
6214 0 : return NT_STATUS_NO_SUCH_USER;
6215 : }
6216 :
6217 0 : if (num_result > 1) {
6218 0 : DEBUG (0, ("ldapsam_set_primary_group: More than one user with name [%s] ?!\n", pdb_get_username(sampass)));
6219 0 : return NT_STATUS_INTERNAL_DB_CORRUPTION;
6220 : }
6221 :
6222 0 : entry = ldap_first_entry(priv2ld(ldap_state), result);
6223 0 : if (!entry) {
6224 0 : return NT_STATUS_UNSUCCESSFUL;
6225 : }
6226 :
6227 : /* retrieve the dn for later use */
6228 0 : dn = smbldap_talloc_dn(mem_ctx, priv2ld(ldap_state), entry);
6229 0 : if (!dn) {
6230 0 : DEBUG(0,("ldapsam_set_primary_group: Out of memory!\n"));
6231 0 : return NT_STATUS_NO_MEMORY;
6232 : }
6233 :
6234 : /* remove the old one, and add the new one, this way we do not risk races */
6235 0 : smbldap_make_mod(priv2ld(ldap_state), entry, &mods, "gidNumber", gidstr);
6236 :
6237 0 : if (mods == NULL) {
6238 0 : TALLOC_FREE(dn);
6239 0 : return NT_STATUS_OK;
6240 : }
6241 :
6242 0 : rc = smbldap_modify(ldap_state->smbldap_state, dn, mods);
6243 0 : TALLOC_FREE(dn);
6244 0 : if (rc != LDAP_SUCCESS) {
6245 0 : DEBUG(0,("ldapsam_set_primary_group: failed to modify [%s] primary group to [%s]\n",
6246 : pdb_get_username(sampass), gidstr));
6247 0 : return NT_STATUS_UNSUCCESSFUL;
6248 : }
6249 :
6250 0 : flush_pwnam_cache();
6251 :
6252 0 : return NT_STATUS_OK;
6253 : }
6254 :
6255 :
6256 : /**********************************************************************
6257 : trusted domains functions
6258 : *********************************************************************/
6259 :
6260 0 : static char *trusteddom_dn(struct ldapsam_privates *ldap_state,
6261 : const char *domain)
6262 : {
6263 0 : return talloc_asprintf(talloc_tos(), "sambaDomainName=%s,%s", domain,
6264 : ldap_state->domain_dn);
6265 : }
6266 :
6267 0 : static bool get_trusteddom_pw_int(struct ldapsam_privates *ldap_state,
6268 : TALLOC_CTX *mem_ctx,
6269 : const char *domain, LDAPMessage **entry)
6270 : {
6271 : int rc;
6272 : char *filter;
6273 0 : int scope = LDAP_SCOPE_SUBTREE;
6274 0 : const char **attrs = NULL; /* NULL: get all attrs */
6275 0 : int attrsonly = 0; /* 0: return values too */
6276 0 : LDAPMessage *result = NULL;
6277 : char *trusted_dn;
6278 : uint32_t num_result;
6279 :
6280 0 : filter = talloc_asprintf(talloc_tos(),
6281 : "(&(objectClass=%s)(sambaDomainName=%s))",
6282 : LDAP_OBJ_TRUSTDOM_PASSWORD, domain);
6283 :
6284 0 : trusted_dn = trusteddom_dn(ldap_state, domain);
6285 0 : if (trusted_dn == NULL) {
6286 0 : return False;
6287 : }
6288 0 : rc = smbldap_search(ldap_state->smbldap_state, trusted_dn, scope,
6289 : filter, attrs, attrsonly, &result);
6290 :
6291 0 : if (result != NULL) {
6292 0 : smbldap_talloc_autofree_ldapmsg(mem_ctx, result);
6293 : }
6294 :
6295 0 : if (rc == LDAP_NO_SUCH_OBJECT) {
6296 0 : *entry = NULL;
6297 0 : return True;
6298 : }
6299 :
6300 0 : if (rc != LDAP_SUCCESS) {
6301 0 : return False;
6302 : }
6303 :
6304 0 : num_result = ldap_count_entries(priv2ld(ldap_state), result);
6305 :
6306 0 : if (num_result > 1) {
6307 0 : DEBUG(1, ("ldapsam_get_trusteddom_pw: more than one "
6308 : "%s object for domain '%s'?!\n",
6309 : LDAP_OBJ_TRUSTDOM_PASSWORD, domain));
6310 0 : return False;
6311 : }
6312 :
6313 0 : if (num_result == 0) {
6314 0 : DEBUG(1, ("ldapsam_get_trusteddom_pw: no "
6315 : "%s object for domain %s.\n",
6316 : LDAP_OBJ_TRUSTDOM_PASSWORD, domain));
6317 0 : *entry = NULL;
6318 : } else {
6319 0 : *entry = ldap_first_entry(priv2ld(ldap_state), result);
6320 : }
6321 :
6322 0 : return True;
6323 : }
6324 :
6325 0 : static bool ldapsam_get_trusteddom_pw(struct pdb_methods *methods,
6326 : const char *domain,
6327 : char** pwd,
6328 : struct dom_sid *sid,
6329 : time_t *pass_last_set_time)
6330 : {
6331 0 : struct ldapsam_privates *ldap_state =
6332 : (struct ldapsam_privates *)methods->private_data;
6333 0 : LDAPMessage *entry = NULL;
6334 :
6335 0 : DEBUG(10, ("ldapsam_get_trusteddom_pw called for domain %s\n", domain));
6336 :
6337 0 : if (!get_trusteddom_pw_int(ldap_state, talloc_tos(), domain, &entry) ||
6338 0 : (entry == NULL))
6339 : {
6340 0 : return False;
6341 : }
6342 :
6343 : /* password */
6344 0 : if (pwd != NULL) {
6345 : char *pwd_str;
6346 0 : pwd_str = smbldap_talloc_single_attribute(priv2ld(ldap_state),
6347 : entry, "sambaClearTextPassword", talloc_tos());
6348 0 : if (pwd_str == NULL) {
6349 0 : return False;
6350 : }
6351 : /* trusteddom_pw routines do not use talloc yet... */
6352 0 : *pwd = SMB_STRDUP(pwd_str);
6353 0 : if (*pwd == NULL) {
6354 0 : return False;
6355 : }
6356 : }
6357 :
6358 : /* last change time */
6359 0 : if (pass_last_set_time != NULL) {
6360 : char *time_str;
6361 0 : time_str = smbldap_talloc_single_attribute(priv2ld(ldap_state),
6362 : entry, "sambaPwdLastSet", talloc_tos());
6363 0 : if (time_str == NULL) {
6364 0 : return False;
6365 : }
6366 0 : *pass_last_set_time = (time_t)atol(time_str);
6367 : }
6368 :
6369 : /* domain sid */
6370 0 : if (sid != NULL) {
6371 : char *sid_str;
6372 : struct dom_sid dom_sid;
6373 0 : sid_str = smbldap_talloc_single_attribute(priv2ld(ldap_state),
6374 : entry, "sambaSID",
6375 : talloc_tos());
6376 0 : if (sid_str == NULL) {
6377 0 : return False;
6378 : }
6379 0 : if (!string_to_sid(&dom_sid, sid_str)) {
6380 0 : return False;
6381 : }
6382 0 : sid_copy(sid, &dom_sid);
6383 : }
6384 :
6385 0 : return True;
6386 : }
6387 :
6388 0 : static bool ldapsam_set_trusteddom_pw(struct pdb_methods *methods,
6389 : const char* domain,
6390 : const char* pwd,
6391 : const struct dom_sid *sid)
6392 : {
6393 0 : struct ldapsam_privates *ldap_state =
6394 : (struct ldapsam_privates *)methods->private_data;
6395 0 : LDAPMessage *entry = NULL;
6396 0 : LDAPMod **mods = NULL;
6397 0 : char *prev_pwd = NULL;
6398 0 : char *trusted_dn = NULL;
6399 : struct dom_sid_buf buf;
6400 : int rc;
6401 :
6402 0 : DEBUG(10, ("ldapsam_set_trusteddom_pw called for domain %s\n", domain));
6403 :
6404 : /*
6405 : * get the current entry (if there is one) in order to put the
6406 : * current password into the previous password attribute
6407 : */
6408 0 : if (!get_trusteddom_pw_int(ldap_state, talloc_tos(), domain, &entry)) {
6409 0 : return False;
6410 : }
6411 :
6412 0 : mods = NULL;
6413 0 : smbldap_make_mod(priv2ld(ldap_state), entry, &mods, "objectClass",
6414 : LDAP_OBJ_TRUSTDOM_PASSWORD);
6415 0 : smbldap_make_mod(priv2ld(ldap_state), entry, &mods, "sambaDomainName",
6416 : domain);
6417 0 : smbldap_make_mod(priv2ld(ldap_state), entry, &mods, "sambaSID",
6418 0 : dom_sid_str_buf(sid, &buf));
6419 0 : smbldap_make_mod(priv2ld(ldap_state), entry, &mods, "sambaPwdLastSet",
6420 0 : talloc_asprintf(talloc_tos(), "%li", (long int)time(NULL)));
6421 0 : smbldap_make_mod(priv2ld(ldap_state), entry, &mods,
6422 : "sambaClearTextPassword", pwd);
6423 :
6424 0 : if (entry != NULL) {
6425 0 : prev_pwd = smbldap_talloc_single_attribute(priv2ld(ldap_state),
6426 : entry, "sambaClearTextPassword", talloc_tos());
6427 0 : if (prev_pwd != NULL) {
6428 0 : smbldap_make_mod(priv2ld(ldap_state), entry, &mods,
6429 : "sambaPreviousClearTextPassword",
6430 : prev_pwd);
6431 : }
6432 : }
6433 :
6434 0 : smbldap_talloc_autofree_ldapmod(talloc_tos(), mods);
6435 :
6436 0 : trusted_dn = trusteddom_dn(ldap_state, domain);
6437 0 : if (trusted_dn == NULL) {
6438 0 : return False;
6439 : }
6440 0 : if (entry == NULL) {
6441 0 : rc = smbldap_add(ldap_state->smbldap_state, trusted_dn, mods);
6442 : } else {
6443 0 : rc = smbldap_modify(ldap_state->smbldap_state, trusted_dn, mods);
6444 : }
6445 :
6446 0 : if (rc != LDAP_SUCCESS) {
6447 0 : DEBUG(1, ("error writing trusted domain password!\n"));
6448 0 : return False;
6449 : }
6450 :
6451 0 : return True;
6452 : }
6453 :
6454 0 : static bool ldapsam_del_trusteddom_pw(struct pdb_methods *methods,
6455 : const char *domain)
6456 : {
6457 : int rc;
6458 0 : struct ldapsam_privates *ldap_state =
6459 : (struct ldapsam_privates *)methods->private_data;
6460 0 : LDAPMessage *entry = NULL;
6461 : const char *trusted_dn;
6462 :
6463 0 : if (!get_trusteddom_pw_int(ldap_state, talloc_tos(), domain, &entry)) {
6464 0 : return False;
6465 : }
6466 :
6467 0 : if (entry == NULL) {
6468 0 : DEBUG(5, ("ldapsam_del_trusteddom_pw: no such trusted domain: "
6469 : "%s\n", domain));
6470 0 : return True;
6471 : }
6472 :
6473 0 : trusted_dn = smbldap_talloc_dn(talloc_tos(), priv2ld(ldap_state),
6474 : entry);
6475 0 : if (trusted_dn == NULL) {
6476 0 : DEBUG(0,("ldapsam_del_trusteddom_pw: Out of memory!\n"));
6477 0 : return False;
6478 : }
6479 :
6480 0 : rc = smbldap_delete(ldap_state->smbldap_state, trusted_dn);
6481 0 : if (rc != LDAP_SUCCESS) {
6482 0 : return False;
6483 : }
6484 :
6485 0 : return True;
6486 : }
6487 :
6488 0 : static NTSTATUS ldapsam_enum_trusteddoms(struct pdb_methods *methods,
6489 : TALLOC_CTX *mem_ctx,
6490 : uint32_t *num_domains,
6491 : struct trustdom_info ***domains)
6492 : {
6493 : int rc;
6494 0 : struct ldapsam_privates *ldap_state =
6495 : (struct ldapsam_privates *)methods->private_data;
6496 : char *filter;
6497 0 : int scope = LDAP_SCOPE_SUBTREE;
6498 0 : const char *attrs[] = { "sambaDomainName", "sambaSID", NULL };
6499 0 : int attrsonly = 0; /* 0: return values too */
6500 0 : LDAPMessage *result = NULL;
6501 0 : LDAPMessage *entry = NULL;
6502 :
6503 0 : filter = talloc_asprintf(talloc_tos(), "(objectClass=%s)",
6504 : LDAP_OBJ_TRUSTDOM_PASSWORD);
6505 :
6506 0 : rc = smbldap_search(ldap_state->smbldap_state,
6507 0 : ldap_state->domain_dn,
6508 : scope,
6509 : filter,
6510 : attrs,
6511 : attrsonly,
6512 : &result);
6513 :
6514 0 : if (result != NULL) {
6515 0 : smbldap_talloc_autofree_ldapmsg(mem_ctx, result);
6516 : }
6517 :
6518 0 : if (rc != LDAP_SUCCESS) {
6519 0 : return NT_STATUS_UNSUCCESSFUL;
6520 : }
6521 :
6522 0 : *num_domains = 0;
6523 0 : if (!(*domains = talloc_array(mem_ctx, struct trustdom_info *, 1))) {
6524 0 : DEBUG(1, ("talloc failed\n"));
6525 0 : return NT_STATUS_NO_MEMORY;
6526 : }
6527 :
6528 0 : for (entry = ldap_first_entry(priv2ld(ldap_state), result);
6529 0 : entry != NULL;
6530 0 : entry = ldap_next_entry(priv2ld(ldap_state), entry))
6531 : {
6532 : char *dom_name, *dom_sid_str;
6533 : struct trustdom_info *dom_info;
6534 :
6535 0 : dom_info = talloc(*domains, struct trustdom_info);
6536 0 : if (dom_info == NULL) {
6537 0 : DEBUG(1, ("talloc failed\n"));
6538 0 : return NT_STATUS_NO_MEMORY;
6539 : }
6540 :
6541 0 : dom_name = smbldap_talloc_single_attribute(priv2ld(ldap_state),
6542 : entry,
6543 : "sambaDomainName",
6544 : talloc_tos());
6545 0 : if (dom_name == NULL) {
6546 0 : DEBUG(1, ("talloc failed\n"));
6547 0 : return NT_STATUS_NO_MEMORY;
6548 : }
6549 0 : dom_info->name = dom_name;
6550 :
6551 0 : dom_sid_str = smbldap_talloc_single_attribute(
6552 : priv2ld(ldap_state), entry, "sambaSID",
6553 : talloc_tos());
6554 0 : if (dom_sid_str == NULL) {
6555 0 : DEBUG(1, ("talloc failed\n"));
6556 0 : return NT_STATUS_NO_MEMORY;
6557 : }
6558 0 : if (!string_to_sid(&dom_info->sid, dom_sid_str)) {
6559 0 : DEBUG(1, ("Error calling string_to_sid on SID %s\n",
6560 : dom_sid_str));
6561 0 : return NT_STATUS_UNSUCCESSFUL;
6562 : }
6563 :
6564 0 : ADD_TO_ARRAY(*domains, struct trustdom_info *, dom_info,
6565 : domains, num_domains);
6566 :
6567 0 : if (*domains == NULL) {
6568 0 : DEBUG(1, ("talloc failed\n"));
6569 0 : return NT_STATUS_NO_MEMORY;
6570 : }
6571 : }
6572 :
6573 0 : DEBUG(5, ("ldapsam_enum_trusteddoms: got %d domains\n", *num_domains));
6574 0 : return NT_STATUS_OK;
6575 : }
6576 :
6577 :
6578 : /**********************************************************************
6579 : Housekeeping
6580 : *********************************************************************/
6581 :
6582 0 : static void free_private_data(void **vp)
6583 : {
6584 0 : struct ldapsam_privates **ldap_state = (struct ldapsam_privates **)vp;
6585 :
6586 0 : smbldap_free_struct(&(*ldap_state)->smbldap_state);
6587 :
6588 0 : if ((*ldap_state)->result != NULL) {
6589 0 : ldap_msgfree((*ldap_state)->result);
6590 0 : (*ldap_state)->result = NULL;
6591 : }
6592 0 : if ((*ldap_state)->domain_dn != NULL) {
6593 0 : SAFE_FREE((*ldap_state)->domain_dn);
6594 : }
6595 :
6596 0 : *ldap_state = NULL;
6597 :
6598 : /* No need to free any further, as it is talloc()ed */
6599 0 : }
6600 :
6601 : /*********************************************************************
6602 : Intitalise the parts of the pdb_methods structure that are common to
6603 : all pdb_ldap modes
6604 : *********************************************************************/
6605 :
6606 0 : static NTSTATUS pdb_init_ldapsam_common(struct pdb_methods **pdb_method, const char *location)
6607 : {
6608 : NTSTATUS nt_status;
6609 : struct ldapsam_privates *ldap_state;
6610 0 : char *bind_dn = NULL;
6611 0 : char *bind_secret = NULL;
6612 :
6613 0 : if (!NT_STATUS_IS_OK(nt_status = make_pdb_method( pdb_method ))) {
6614 0 : return nt_status;
6615 : }
6616 :
6617 0 : (*pdb_method)->name = "ldapsam";
6618 :
6619 0 : (*pdb_method)->getsampwnam = ldapsam_getsampwnam;
6620 0 : (*pdb_method)->getsampwsid = ldapsam_getsampwsid;
6621 0 : (*pdb_method)->add_sam_account = ldapsam_add_sam_account;
6622 0 : (*pdb_method)->update_sam_account = ldapsam_update_sam_account;
6623 0 : (*pdb_method)->delete_sam_account = ldapsam_delete_sam_account;
6624 0 : (*pdb_method)->rename_sam_account = ldapsam_rename_sam_account;
6625 :
6626 0 : (*pdb_method)->getgrsid = ldapsam_getgrsid;
6627 0 : (*pdb_method)->getgrgid = ldapsam_getgrgid;
6628 0 : (*pdb_method)->getgrnam = ldapsam_getgrnam;
6629 0 : (*pdb_method)->add_group_mapping_entry = ldapsam_add_group_mapping_entry;
6630 0 : (*pdb_method)->update_group_mapping_entry = ldapsam_update_group_mapping_entry;
6631 0 : (*pdb_method)->delete_group_mapping_entry = ldapsam_delete_group_mapping_entry;
6632 0 : (*pdb_method)->enum_group_mapping = ldapsam_enum_group_mapping;
6633 :
6634 0 : (*pdb_method)->get_account_policy = ldapsam_get_account_policy;
6635 0 : (*pdb_method)->set_account_policy = ldapsam_set_account_policy;
6636 :
6637 0 : (*pdb_method)->get_seq_num = ldapsam_get_seq_num;
6638 :
6639 0 : (*pdb_method)->capabilities = ldapsam_capabilities;
6640 0 : (*pdb_method)->new_rid = ldapsam_new_rid;
6641 :
6642 0 : (*pdb_method)->get_trusteddom_pw = ldapsam_get_trusteddom_pw;
6643 0 : (*pdb_method)->set_trusteddom_pw = ldapsam_set_trusteddom_pw;
6644 0 : (*pdb_method)->del_trusteddom_pw = ldapsam_del_trusteddom_pw;
6645 0 : (*pdb_method)->enum_trusteddoms = ldapsam_enum_trusteddoms;
6646 :
6647 : /* TODO: Setup private data and free */
6648 :
6649 0 : if ( !(ldap_state = talloc_zero(*pdb_method, struct ldapsam_privates)) ) {
6650 0 : DEBUG(0, ("pdb_init_ldapsam_common: talloc() failed for ldapsam private_data!\n"));
6651 0 : return NT_STATUS_NO_MEMORY;
6652 : }
6653 :
6654 0 : if (!fetch_ldap_pw(&bind_dn, &bind_secret)) {
6655 0 : DEBUG(0, ("pdb_init_ldapsam_common: Failed to retrieve LDAP password from secrets.tdb\n"));
6656 0 : return NT_STATUS_NO_MEMORY;
6657 : }
6658 :
6659 0 : nt_status = smbldap_init(*pdb_method, pdb_get_tevent_context(),
6660 : location, false, bind_dn, bind_secret,
6661 : &ldap_state->smbldap_state);
6662 0 : memset(bind_secret, '\0', strlen(bind_secret));
6663 0 : SAFE_FREE(bind_secret);
6664 0 : SAFE_FREE(bind_dn);
6665 0 : if ( !NT_STATUS_IS_OK(nt_status) ) {
6666 0 : return nt_status;
6667 : }
6668 :
6669 0 : if ( !(ldap_state->domain_name = talloc_strdup(*pdb_method, get_global_sam_name()) ) ) {
6670 0 : return NT_STATUS_NO_MEMORY;
6671 : }
6672 :
6673 0 : (*pdb_method)->private_data = ldap_state;
6674 :
6675 0 : (*pdb_method)->free_private_data = free_private_data;
6676 :
6677 0 : return NT_STATUS_OK;
6678 : }
6679 :
6680 0 : static bool ldapsam_is_responsible_for_wellknown(struct pdb_methods *m)
6681 : {
6682 0 : return true;
6683 : }
6684 :
6685 : /**********************************************************************
6686 : Initialise the normal mode for pdb_ldap
6687 : *********************************************************************/
6688 :
6689 0 : NTSTATUS pdb_ldapsam_init_common(struct pdb_methods **pdb_method,
6690 : const char *location)
6691 : {
6692 : NTSTATUS nt_status;
6693 0 : struct ldapsam_privates *ldap_state = NULL;
6694 : uint32_t alg_rid_base;
6695 0 : char *alg_rid_base_string = NULL;
6696 0 : LDAPMessage *result = NULL;
6697 0 : LDAPMessage *entry = NULL;
6698 : struct dom_sid ldap_domain_sid;
6699 : struct dom_sid secrets_domain_sid;
6700 0 : char *domain_sid_string = NULL;
6701 0 : char *dn = NULL;
6702 0 : char *uri = talloc_strdup( NULL, location );
6703 :
6704 0 : trim_char( uri, '\"', '\"' );
6705 0 : nt_status = pdb_init_ldapsam_common(pdb_method, uri);
6706 :
6707 0 : TALLOC_FREE(uri);
6708 :
6709 0 : if (!NT_STATUS_IS_OK(nt_status)) {
6710 0 : return nt_status;
6711 : }
6712 :
6713 0 : (*pdb_method)->name = "ldapsam";
6714 :
6715 0 : (*pdb_method)->add_aliasmem = ldapsam_add_aliasmem;
6716 0 : (*pdb_method)->del_aliasmem = ldapsam_del_aliasmem;
6717 0 : (*pdb_method)->enum_aliasmem = ldapsam_enum_aliasmem;
6718 0 : (*pdb_method)->enum_alias_memberships = ldapsam_alias_memberships;
6719 0 : (*pdb_method)->search_users = ldapsam_search_users;
6720 0 : (*pdb_method)->search_groups = ldapsam_search_groups;
6721 0 : (*pdb_method)->search_aliases = ldapsam_search_aliases;
6722 0 : (*pdb_method)->is_responsible_for_wellknown =
6723 : ldapsam_is_responsible_for_wellknown;
6724 :
6725 0 : if (lp_parm_bool(-1, "ldapsam", "trusted", False)) {
6726 0 : (*pdb_method)->enum_group_members = ldapsam_enum_group_members;
6727 0 : (*pdb_method)->enum_group_memberships =
6728 : ldapsam_enum_group_memberships;
6729 0 : (*pdb_method)->lookup_rids = ldapsam_lookup_rids;
6730 0 : (*pdb_method)->sid_to_id = ldapsam_sid_to_id;
6731 0 : (*pdb_method)->id_to_sid = ldapsam_id_to_sid;
6732 :
6733 0 : if (lp_parm_bool(-1, "ldapsam", "editposix", False)) {
6734 0 : (*pdb_method)->create_user = ldapsam_create_user;
6735 0 : (*pdb_method)->delete_user = ldapsam_delete_user;
6736 0 : (*pdb_method)->create_dom_group = ldapsam_create_dom_group;
6737 0 : (*pdb_method)->delete_dom_group = ldapsam_delete_dom_group;
6738 0 : (*pdb_method)->add_groupmem = ldapsam_add_groupmem;
6739 0 : (*pdb_method)->del_groupmem = ldapsam_del_groupmem;
6740 0 : (*pdb_method)->set_unix_primary_group = ldapsam_set_primary_group;
6741 : }
6742 : }
6743 :
6744 0 : ldap_state = (struct ldapsam_privates *)((*pdb_method)->private_data);
6745 0 : ldap_state->schema_ver = SCHEMAVER_SAMBASAMACCOUNT;
6746 :
6747 : /* Try to setup the Domain Name, Domain SID, algorithmic rid base */
6748 :
6749 0 : nt_status = smbldap_search_domain_info(ldap_state->smbldap_state,
6750 : &result,
6751 : ldap_state->domain_name, True);
6752 :
6753 0 : if ( !NT_STATUS_IS_OK(nt_status) ) {
6754 0 : DEBUG(0, ("pdb_init_ldapsam: WARNING: Could not get domain "
6755 : "info, nor add one to the domain. "
6756 : "We cannot work reliably without it.\n"));
6757 0 : return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
6758 : }
6759 :
6760 : /* Given that the above might fail, everything below this must be
6761 : * optional */
6762 :
6763 0 : entry = ldap_first_entry(smbldap_get_ldap(ldap_state->smbldap_state),
6764 : result);
6765 0 : if (!entry) {
6766 0 : DEBUG(0, ("pdb_init_ldapsam: Could not get domain info "
6767 : "entry\n"));
6768 0 : ldap_msgfree(result);
6769 0 : return NT_STATUS_UNSUCCESSFUL;
6770 : }
6771 :
6772 0 : dn = smbldap_talloc_dn(talloc_tos(),
6773 : smbldap_get_ldap(ldap_state->smbldap_state),
6774 : entry);
6775 0 : if (!dn) {
6776 0 : ldap_msgfree(result);
6777 0 : return NT_STATUS_UNSUCCESSFUL;
6778 : }
6779 :
6780 0 : ldap_state->domain_dn = smb_xstrdup(dn);
6781 0 : TALLOC_FREE(dn);
6782 :
6783 0 : domain_sid_string = smbldap_talloc_single_attribute(
6784 : smbldap_get_ldap(ldap_state->smbldap_state),
6785 : entry,
6786 : get_userattr_key2string(ldap_state->schema_ver,
6787 : LDAP_ATTR_USER_SID),
6788 : talloc_tos());
6789 :
6790 0 : if (domain_sid_string) {
6791 : bool found_sid;
6792 0 : if (!string_to_sid(&ldap_domain_sid, domain_sid_string)) {
6793 0 : DEBUG(1, ("pdb_init_ldapsam: SID [%s] could not be "
6794 : "read as a valid SID\n", domain_sid_string));
6795 0 : ldap_msgfree(result);
6796 0 : TALLOC_FREE(domain_sid_string);
6797 0 : return NT_STATUS_INVALID_PARAMETER;
6798 : }
6799 0 : found_sid = PDB_secrets_fetch_domain_sid(ldap_state->domain_name,
6800 : &secrets_domain_sid);
6801 0 : if (!found_sid || !dom_sid_equal(&secrets_domain_sid,
6802 : &ldap_domain_sid)) {
6803 : struct dom_sid_buf buf1, buf2;
6804 0 : DEBUG(1, ("pdb_init_ldapsam: Resetting SID for domain "
6805 : "%s based on pdb_ldap results %s -> %s\n",
6806 : ldap_state->domain_name,
6807 : dom_sid_str_buf(&secrets_domain_sid, &buf1),
6808 : dom_sid_str_buf(&ldap_domain_sid, &buf2)));
6809 :
6810 : /* reset secrets.tdb sid */
6811 0 : PDB_secrets_store_domain_sid(ldap_state->domain_name,
6812 : &ldap_domain_sid);
6813 0 : DEBUG(1, ("New global sam SID: %s\n",
6814 : dom_sid_str_buf(get_global_sam_sid(),
6815 : &buf1)));
6816 : }
6817 0 : sid_copy(&ldap_state->domain_sid, &ldap_domain_sid);
6818 0 : TALLOC_FREE(domain_sid_string);
6819 : }
6820 :
6821 0 : alg_rid_base_string = smbldap_talloc_single_attribute(
6822 : smbldap_get_ldap(ldap_state->smbldap_state),
6823 : entry,
6824 : get_attr_key2string( dominfo_attr_list,
6825 : LDAP_ATTR_ALGORITHMIC_RID_BASE ),
6826 : talloc_tos());
6827 0 : if (alg_rid_base_string) {
6828 0 : alg_rid_base = (uint32_t)atol(alg_rid_base_string);
6829 0 : if (alg_rid_base != algorithmic_rid_base()) {
6830 0 : DEBUG(0, ("The value of 'algorithmic RID base' has "
6831 : "changed since the LDAP\n"
6832 : "database was initialised. Aborting. \n"));
6833 0 : ldap_msgfree(result);
6834 0 : TALLOC_FREE(alg_rid_base_string);
6835 0 : return NT_STATUS_UNSUCCESSFUL;
6836 : }
6837 0 : TALLOC_FREE(alg_rid_base_string);
6838 : }
6839 0 : ldap_msgfree(result);
6840 :
6841 0 : return NT_STATUS_OK;
6842 : }
6843 :
6844 877 : NTSTATUS pdb_ldapsam_init(TALLOC_CTX *ctx)
6845 : {
6846 : NTSTATUS nt_status;
6847 :
6848 877 : nt_status = smb_register_passdb(PASSDB_INTERFACE_VERSION,
6849 : "ldapsam",
6850 : pdb_ldapsam_init_common);
6851 877 : if (!NT_STATUS_IS_OK(nt_status)) {
6852 0 : return nt_status;
6853 : }
6854 :
6855 : /* Let pdb_nds register backends */
6856 877 : pdb_nds_init(ctx);
6857 :
6858 877 : return NT_STATUS_OK;
6859 : }
|