2 Unix SMB/CIFS implementation.
3 Active Directory SAM backend, for simulate a W2K DC in mixed mode.
5 Copyright (C) Stefan (metze) Metzmacher 2002
6 Copyright (C) Andrew Bartlett 2002
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
28 static int sam_ads_debug_level = DBGC_SAM;
31 #define DBGC_CLASS sam_ads_debug_level
34 #define FIXME( body ) { DEBUG(0,("FIXME: "));\
38 #define ADS_STATUS_OK ADS_ERROR(0)
39 #define ADS_STATUS_UNSUCCESSFUL ADS_ERROR_NT(NT_STATUS_UNSUCCESSFUL)
40 #define ADS_STATUS_NOT_IMPLEMENTED ADS_ERROR_NT(NT_STATUS_NOT_IMPLEMENTED)
43 #define ADS_SUBTREE_BUILTIN "CN=Builtin,"
44 #define ADS_SUBTREE_COMPUTERS "CN=Computers,"
45 #define ADS_SUBTREE_DC "CN=Domain Controllers,"
46 #define ADS_SUBTREE_USERS "CN=Users,"
47 #define ADS_ROOT_TREE ""
48 /* Here are private module structs and functions */
50 typedef struct sam_ads_privates {
51 ADS_STRUCT *ads_struct;
57 /* did we need something more? */
61 /* get only these LDAP attributes, witch we really need for an account */
62 const char *account_attrs[] = { "objectSid",
82 "primaryGroupID",/* 513 */
83 "nsNPAllowDialIn",/* TRUE */
84 "userParameters",/* Dial Back number ...*/
87 "adminCount",/* 1 or 0 */
91 "instanceType",/* 4 */
92 "name", /* sync with cn */
94 /* "nTSecurityDescriptor", */
97 /* get only these LDAP attributes, witch we really need for a group */
98 const char *group_attrs[] = {"objectSid",
105 "name", /* sync with cn */
106 /* "nTSecurityDescriptor", */
110 /***************************************************
111 return our ads connection. We keep the connection
112 open to make things faster
113 ****************************************************/
114 static ADS_STATUS sam_ads_cached_connection(SAM_ADS_PRIVATES *privates)
116 ADS_STRUCT *ads_struct;
117 ADS_STATUS ads_status;
119 if (!privates->ads_struct) {
120 privates->ads_struct = ads_init_simple();
121 ads_struct = privates->ads_struct;
122 ads_struct->server.ldap_uri = smb_xstrdup(privates->ldap_uri);
123 if ((!privates->ads_bind_dn) || (!*privates->ads_bind_dn)) {
124 ads_struct->auth.flags |= ADS_AUTH_ANON_BIND;
126 ads_struct->auth.user_name
127 = smb_xstrdup(privates->ads_bind_dn);
128 if (privates->ads_bind_pw) {
129 ads_struct->auth.password
130 = smb_xstrdup(privates->ads_bind_pw);
133 if (privates->bind_plaintext) {
134 ads_struct->auth.flags |= ADS_AUTH_SIMPLE_BIND;
137 ads_struct = privates->ads_struct;
140 if (ads_struct->ld != NULL) {
141 /* connection has been opened. ping server. */
142 struct sockaddr_un addr;
145 if (ldap_get_option(ads_struct->ld, LDAP_OPT_DESC, &sd) == 0 &&
146 getpeername(sd, (struct sockaddr *) &addr, &len) < 0) {
147 /* the other end has died. reopen. */
148 ldap_unbind_ext(ads_struct->ld, NULL, NULL);
149 ads_struct->ld = NULL;
153 if (ads_struct->ld != NULL) {
154 DEBUG(5,("sam_ads_cached_connection: allready connected to the LDAP server\n"));
158 ads_status = ads_connect(ads_struct);
160 ads_status = ads_server_info(ads_struct);
161 if (!ADS_ERR_OK(ads_status)) {
162 DEBUG(0,("Can't set server info: %s\n",ads_errstr(ads_status)));
163 /* return ads_status; */ FIXME("for now we only warn!\n");
166 DEBUG(2, ("sam_ads_cached_connection: succesful connection to the LDAP server\n"));
170 static ADS_STATUS sam_ads_do_search(SAM_ADS_PRIVATES *privates, const char *bind_path, int scope, const char *exp, const char **attrs, void **res)
172 ADS_STATUS ads_status = ADS_ERROR_NT(NT_STATUS_UNSUCCESSFUL);
174 ads_status = sam_ads_cached_connection(privates);
175 if (!ADS_ERR_OK(ads_status))
178 return ads_do_search_retry(privates->ads_struct, bind_path, scope, exp, attrs, res);
182 /*********************************************
183 here we have to check the update serial number
184 - this is the core of the ldap cache
185 *********************************************/
186 static ADS_STATUS sam_ads_usn_is_valid(SAM_ADS_PRIVATES *privates, uint32 usn_in, uint32 *usn_out)
188 ADS_STATUS ads_status = ADS_ERROR_NT(NT_STATUS_UNSUCCESSFUL);
190 SAM_ASSERT(privates && privates->ads_struct && usn_out);
192 ads_status = ads_USN(privates->ads_struct, usn_out);
193 if (!ADS_ERR_OK(ads_status))
196 if (*usn_out == usn_in)
202 /***********************************************
203 Initialize SAM_ACCOUNT_HANDLE from an ADS query
204 ************************************************/
206 static ADS_STATUS ads_entry2sam_account_handle(SAM_ADS_PRIVATES *privates, SAM_ACCOUNT_HANDLE *account ,void *msg)
208 ADS_STATUS ads_status = ADS_ERROR_NT(NT_STATUS_NO_SUCH_USER);
209 NTSTATUS nt_status = NT_STATUS_NO_SUCH_USER;
210 ADS_STRUCT *ads_struct = privates->ads_struct;
211 TALLOC_CTX *mem_ctx = account->mem_ctx;
212 char *tmp_str = NULL;
214 SAM_ASSERT(privates && ads_struct && account && mem_ctx && msg);
216 FIXME("should we really use ads_pull_username()(or ads_pull_string())?\n");
217 if ((account->private.account_name = ads_pull_username(ads_struct, mem_ctx, msg))==NULL) {
218 DEBUG(0,("ads_pull_username failed\n"));
219 return ADS_ERROR_NT(NT_STATUS_NO_SUCH_USER);
222 if ((account->private.full_name = ads_pull_string(ads_struct, mem_ctx, msg,"name"))==NULL) {
223 DEBUG(3,("ads_pull_string for 'name' failed - skip\n"));
226 if ((account->private.acct_desc = ads_pull_string(ads_struct, mem_ctx, msg,"description"))!=NULL) {
227 DEBUG(3,("ads_pull_string for 'acct_desc' failed - skip\n"));
230 if ((account->private.home_dir = ads_pull_string(ads_struct, mem_ctx, msg,"homeDirectory"))!=NULL) {
231 DEBUG(3,("ads_pull_string for 'homeDirectory' failed - skip\n"));
234 if ((account->private.dir_drive = ads_pull_string(ads_struct, mem_ctx, msg,"homeDrive"))!=NULL) {
235 DEBUG(3,("ads_pull_string for 'homeDrive' failed - skip\n"));
238 if ((account->private.profile_path = ads_pull_string(ads_struct, mem_ctx, msg,"profilePath"))!=NULL) {
239 DEBUG(3,("ads_pull_string for 'profilePath' failed - skip\n"));
242 if ((account->private.logon_script = ads_pull_string(ads_struct, mem_ctx, msg,"scriptPath"))!=NULL) {
243 DEBUG(3,("ads_pull_string for 'scriptPath' failed - skip\n"));
246 FIXME("check 'nsNPAllowDialIn' for munged_dial!\n");
247 if ((account->private.munged_dial = ads_pull_string(ads_struct, mem_ctx, msg,"userParameters"))!=NULL) {
248 DEBUG(3,("ads_pull_string for 'userParameters' failed - skip\n"));
251 if ((account->private.unix_home_dir = ads_pull_string(ads_struct, mem_ctx, msg,"msSFUHomeDrirectory"))!=NULL) {
252 DEBUG(3,("ads_pull_string for 'msSFUHomeDrirectory' failed - skip\n"));
256 FIXME("use function intern mem_ctx for pwdLastSet\n");
257 if ((tmp_str = ads_pull_string(ads_struct, mem_ctx, msg,"pwdLastSet"))!=NULL) {
258 DEBUG(3,("ads_pull_string for 'pwdLastSet' failed - skip\n"));
260 account->private.pass_last_set_time = ads_parse_nttime(tmp_str);
267 typedef struct sam_account_handle {
269 uint32 access_granted;
270 const struct sam_methods *current_sam_methods; /* sam_methods creating this handle */
271 void (*free_fn)(struct sam_account_handle **);
272 struct sam_account_data {
274 NTTIME logon_time; /* logon time */
275 NTTIME logoff_time; /* logoff time */
276 NTTIME kickoff_time; /* kickoff time */
277 NTTIME pass_last_set_time; /* password last set time */
278 NTTIME pass_can_change_time; /* password can change time */
279 NTTIME pass_must_change_time; /* password must change time */
280 char * account_name; /* account_name string */
281 SAM_DOMAIN_HANDLE * domain; /* domain of account */
282 char *full_name; /* account's full name string */
283 char *unix_home_dir; /* UNIX home directory string */
284 char *home_dir; /* home directory string */
285 char *dir_drive; /* home directory drive string */
286 char *logon_script; /* logon script string */
287 char *profile_path; /* profile path string */
288 char *acct_desc; /* account description string */
289 char *workstations; /* login from workstations string */
290 char *unknown_str; /* don't know what this is, yet. */
291 char *munged_dial; /* munged path name and dial-back tel number */
292 DOM_SID account_sid; /* Primary Account SID */
293 DOM_SID group_sid; /* Primary Group SID */
294 DATA_BLOB lm_pw; /* .data is Null if no password */
295 DATA_BLOB nt_pw; /* .data is Null if no password */
296 char *plaintext_pw; /* if Null not available */
297 uint16 acct_ctrl; /* account info (ACB_xxxx bit-mask) */
298 uint32 unknown_1; /* 0x00ff ffff */
299 uint16 logon_divs; /* 168 - number of hours in a week */
300 uint32 hours_len; /* normally 21 bytes */
301 uint8 hours[MAX_HOURS_LEN];
302 uint32 unknown_2; /* 0x0002 0000 */
303 uint32 unknown_3; /* 0x0000 04ec */
305 } SAM_ACCOUNT_HANDLE;
312 /***********************************************
313 Initialize SAM_GROUP_ENUM from an ads entry
314 ************************************************/
316 static ADS_STATUS ads_entry2sam_group_enum(SAM_ADS_PRIVATES *privates, TALLOC_CTX *mem_ctx, SAM_GROUP_ENUM **group_enum,const void *entry)
318 ADS_STATUS ads_status = ADS_STATUS_UNSUCCESSFUL;
319 ADS_STRUCT *ads_struct = privates->ads_struct;
320 SAM_GROUP_ENUM __group_enum;
321 SAM_GROUP_ENUM *_group_enum = &__group_enum;
323 SAM_ASSERT(privates && ads_struct && mem_ctx && group_enum && entry);
325 *group_enum = _group_enum;
327 DEBUG(3,("sam_ads: ads_entry2sam_account_handle\n"));
329 if (!ads_pull_sid(ads_struct, &entry, "objectSid", &(_group_enum->sid))) {
330 DEBUG(0,("No sid for!?\n"));
331 return ADS_STATUS_UNSUCCESSFUL;
334 if (!(_group_enum->group_name = ads_pull_string(ads_struct, mem_ctx, &entry, "sAMAccountName"))) {
335 DEBUG(0,("No groupname found"));
336 return ADS_STATUS_UNSUCCESSFUL;
339 if (!(_group_enum->group_desc = ads_pull_string(ads_struct, mem_ctx, &entry, "desciption"))) {
340 DEBUG(0,("No description found"));
341 return ADS_STATUS_UNSUCCESSFUL;
344 DEBUG(0,("sAMAccountName: %s\ndescription: %s\nobjectSid: %s\n",
345 _group_enum->group_name,
346 _group_enum->group_desc,
347 sid_string_static(&(_group_enum->sid))
353 static ADS_STATUS sam_ads_access_check(SAM_ADS_PRIVATES *privates, const SEC_DESC *sd, const NT_USER_TOKEN *access_token, uint32 access_desired, uint32 *acc_granted)
355 ADS_STATUS ads_status = ADS_ERROR_NT(NT_STATUS_ACCESS_DENIED);
357 uint32 my_acc_granted;
359 SAM_ASSERT(privates && sd && access_token);
360 /* acc_granted can be set to NULL */
362 /* the steps you need are:
363 1. get_sec_desc for sid
364 2. se_map_generic(accessdesired, generic_mapping)
365 3. se_access_check() */
367 if (!se_access_check(sd, access_token, access_desired, (acc_granted)?acc_granted:&my_acc_granted, &nt_status)) {
368 DEBUG(3,("sam_ads_access_check: ACCESS DENIED\n"));
369 ads_status = ADS_ERROR_NT(nt_status);
372 ads_status = ADS_ERROR_NT(nt_status);
376 static ADS_STATUS sam_ads_get_tree_sec_desc(SAM_ADS_PRIVATES *privates, const char *subtree, SEC_DESC **sd)
378 ADS_STATUS ads_status = ADS_ERROR_NT(NT_STATUS_INVALID_PARAMETER);
379 ADS_STRUCT *ads_struct = privates->ads_struct;
380 TALLOC_CTX *mem_ctx = privates->mem_ctx;
384 const char *sec_desc_attrs[] = {"nTSecurityDescriptor",NULL};
386 SAM_ASSERT(privates && ads_struct && mem_ctx && sd);
390 asprintf(&search_path, "%s%s",subtree,ads_struct->config.bind_path);
392 asprintf(&search_path, "%s","");
394 ads_status = sam_ads_do_search(privates, search_path, LDAP_SCOPE_BASE, "(objectClass=*)", sec_desc_attrs, &sec_desc_res);
395 SAFE_FREE(search_path);
396 if (!ADS_ERR_OK(ads_status))
399 if ((sec_desc_msg = ads_first_entry(ads_struct, sec_desc_res))==NULL) {
400 ads_status = ADS_ERROR_NT(NT_STATUS_INVALID_PARAMETER);
404 if (!ads_pull_sd(ads_struct, mem_ctx, sec_desc_msg, sec_desc_attrs[0], sd)) {
406 ads_status = ADS_ERROR_NT(NT_STATUS_INVALID_PARAMETER);
413 static ADS_STATUS sam_ads_account_policy_get(SAM_ADS_PRIVATES *privates, int field, uint32 *value)
415 ADS_STATUS ads_status = ADS_ERROR_NT(NT_STATUS_INVALID_PARAMETER);
416 ADS_STRUCT *ads_struct = privates->ads_struct;
419 const char *ap_attrs[] = {"minPwdLength",/* AP_MIN_PASSWORD_LEN */
420 "pwdHistoryLength",/* AP_PASSWORD_HISTORY */
421 "AP_USER_MUST_LOGON_TO_CHG_PASS",/* AP_USER_MUST_LOGON_TO_CHG_PASS */
422 "maxPwdAge",/* AP_MAX_PASSWORD_AGE */
423 "minPwdAge",/* AP_MIN_PASSWORD_AGE */
424 "lockoutDuration",/* AP_LOCK_ACCOUNT_DURATION */
425 "AP_RESET_COUNT_TIME",/* AP_RESET_COUNT_TIME */
426 "AP_BAD_ATTEMPT_LOCKOUT",/* AP_BAD_ATTEMPT_LOCKOUT */
427 "AP_TIME_TO_LOGOUT",/* AP_TIME_TO_LOGOUT */
429 /*lockOutObservationWindow
430 lockoutThreshold $ pwdProperties*/
432 static uint32 ap_usn = 0;
435 SAM_ASSERT(privates && ads_struct && value);
437 FIXME("We need to decode all account_policy attributes!\n");
439 ads_status = sam_ads_usn_is_valid(privates,ap_usn,&tmp_usn);
440 if (!ADS_ERR_OK(ads_status)) {
441 ads_status = sam_ads_do_search(privates, ads_struct->config.bind_path, LDAP_SCOPE_BASE, "(objectClass=*)", ap_attrs, &ap_res);
442 if (!ADS_ERR_OK(ads_status))
445 if (ads_count_replies(ads_struct, ap_res) != 1) {
446 ads_msgfree(ads_struct, ap_res);
447 return ADS_ERROR(LDAP_NO_RESULTS_RETURNED);
450 if (!(ap_msg = ads_first_entry(ads_struct, ap_res))) {
451 ads_msgfree(ads_struct, ap_res);
452 return ADS_ERROR(LDAP_NO_RESULTS_RETURNED);
455 if (!ads_pull_uint32(ads_struct, ap_msg, ap_attrs[0], &ap[0])) {
456 /* AP_MIN_PASSWORD_LEN */
457 ap[0] = MINPASSWDLENGTH;/* 5 chars minimum */
459 if (!ads_pull_uint32(ads_struct, ap_msg, ap_attrs[1], &ap[1])) {
460 /* AP_PASSWORD_HISTORY */
461 ap[1] = 0;/* don't keep any old password */
463 if (!ads_pull_uint32(ads_struct, ap_msg, ap_attrs[2], &ap[2])) {
464 /* AP_USER_MUST_LOGON_TO_CHG_PASS */
465 ap[2] = 0;/* don't force user to logon */
467 if (!ads_pull_uint32(ads_struct, ap_msg, ap_attrs[3], &ap[3])) {
468 /* AP_MAX_PASSWORD_AGE */
469 ap[3] = MAX_PASSWORD_AGE;/* 21 days */
471 if (!ads_pull_uint32(ads_struct, ap_msg, ap_attrs[4], &ap[4])) {
472 /* AP_MIN_PASSWORD_AGE */
473 ap[4] = 0;/* 0 days */
475 if (!ads_pull_uint32(ads_struct, ap_msg, ap_attrs[5], &ap[5])) {
476 /* AP_LOCK_ACCOUNT_DURATION */
477 ap[5] = 0;/* lockout for 0 minutes */
479 if (!ads_pull_uint32(ads_struct, ap_msg, ap_attrs[6], &ap[6])) {
480 /* AP_RESET_COUNT_TIME */
481 ap[6] = 0;/* reset immediatly */
483 if (!ads_pull_uint32(ads_struct, ap_msg, ap_attrs[7], &ap[7])) {
484 /* AP_BAD_ATTEMPT_LOCKOUT */
485 ap[7] = 0;/* don't lockout */
487 if (!ads_pull_uint32(ads_struct, ap_msg, ap_attrs[8], &ap[8])) {
488 /* AP_TIME_TO_LOGOUT */
489 ap[8] = -1;/* don't force logout */
492 ads_msgfree(ads_struct, ap_res);
497 case AP_MIN_PASSWORD_LEN:
499 ads_status = ADS_ERROR_NT(NT_STATUS_OK);
501 case AP_PASSWORD_HISTORY:
503 ads_status = ADS_ERROR_NT(NT_STATUS_OK);
505 case AP_USER_MUST_LOGON_TO_CHG_PASS:
507 ads_status = ADS_ERROR_NT(NT_STATUS_OK);
509 case AP_MAX_PASSWORD_AGE:
511 ads_status = ADS_ERROR_NT(NT_STATUS_OK);
513 case AP_MIN_PASSWORD_AGE:
515 ads_status = ADS_ERROR_NT(NT_STATUS_OK);
517 case AP_LOCK_ACCOUNT_DURATION:
519 ads_status = ADS_ERROR_NT(NT_STATUS_OK);
521 case AP_RESET_COUNT_TIME:
523 ads_status = ADS_ERROR_NT(NT_STATUS_OK);
525 case AP_BAD_ATTEMPT_LOCKOUT:
527 ads_status = ADS_ERROR_NT(NT_STATUS_OK);
529 case AP_TIME_TO_LOGOUT:
531 ads_status = ADS_ERROR_NT(NT_STATUS_OK);
533 default: *value = 0; break;
540 /**********************************
541 Now the functions off the SAM API
542 ***********************************/
545 static NTSTATUS sam_ads_get_sec_desc(const SAM_METHODS *sam_method, const NT_USER_TOKEN *access_token,
546 const DOM_SID *sid, SEC_DESC **sd)
548 ADS_STATUS ads_status = ADS_ERROR_NT(NT_STATUS_UNSUCCESSFUL);
549 SAM_ADS_PRIVATES *privates = (struct sam_ads_privates *)sam_method->private_data;
550 ADS_STRUCT *ads_struct = privates->ads_struct;
552 char *sidstr,*filter;
555 const char *sec_desc_attrs[] = {"nTSecurityDescriptor",NULL};
559 SAM_ASSERT(sam_method && access_token && sid && sd);
561 ads_status = sam_ads_get_tree_sec_desc(privates, ADS_ROOT_TREE, &my_sd);
562 if (!ADS_ERR_OK(ads_status))
563 return ads_ntstatus(ads_status);
565 ads_status = sam_ads_access_check(privates, my_sd, access_token, GENERIC_RIGHTS_DOMAIN_READ, NULL);
567 if (!ADS_ERR_OK(ads_status))
568 return ads_ntstatus(ads_status);
570 sidstr = sid_binstring(sid);
571 if (asprintf(&filter, "(objectSid=%s)", sidstr) == -1) {
573 return NT_STATUS_NO_MEMORY;
578 ads_status = sam_ads_do_search(privates,ads_struct->config.bind_path,
579 LDAP_SCOPE_SUBTREE, filter, sec_desc_attrs,
583 if (!ADS_ERR_OK(ads_status)) {
584 return ads_ntstatus(ads_status);
587 if (!(mem_ctx = talloc_init("sec_desc parse in sam_ads"))) {
588 DEBUG(1, ("talloc_init() failed for sec_desc parse context in sam_ads"));
589 ads_msgfree(ads_struct, sec_desc_res);
590 return NT_STATUS_NO_MEMORY;
593 if (ads_count_replies(ads_struct, sec_desc_res) != 1) {
594 DEBUG(1,("sam_ads_get_sec_desc: duplicate or 0 results for sid %s\n",
595 sid_to_string(sid_str, sid)));
596 talloc_destroy(mem_ctx);
597 ads_msgfree(ads_struct, sec_desc_res);
598 return NT_STATUS_UNSUCCESSFUL;
601 if (!(sec_desc_msg = ads_first_entry(ads_struct, sec_desc_res))) {
602 talloc_destroy(mem_ctx);
603 ads_msgfree(ads_struct, sec_desc_res);
604 return NT_STATUS_INVALID_PARAMETER;
607 if (!ads_pull_sd(ads_struct, mem_ctx, sec_desc_msg, sec_desc_attrs[0], sd)) {
608 ads_status = ADS_ERROR_NT(NT_STATUS_INVALID_PARAMETER);
609 talloc_destroy(mem_ctx);
610 ads_msgfree(ads_struct, sec_desc_res);
611 return ads_ntstatus(ads_status);
614 /* now, were we allowed to see the SD we just got? */
616 ads_msgfree(ads_struct, sec_desc_res);
617 talloc_destroy(mem_ctx);
618 return ads_ntstatus(ads_status);
621 static NTSTATUS sam_ads_set_sec_desc(const SAM_METHODS *sam_method, const NT_USER_TOKEN *access_token,
622 const DOM_SID *sid, const SEC_DESC *sd)
624 ADS_STATUS ads_status = ADS_STATUS_NOT_IMPLEMENTED;
625 DEBUG(0,("sam_ads: %s was called!\n",FUNCTION_MACRO));
626 SAM_ASSERT(sam_method);
627 return ads_ntstatus(ads_status);
631 static NTSTATUS sam_ads_lookup_sid(const SAM_METHODS *sam_method, const NT_USER_TOKEN *access_token,
632 TALLOC_CTX *mem_ctx, const DOM_SID *sid, char **name,
633 enum SID_NAME_USE *type)
635 ADS_STATUS ads_status = ADS_ERROR_NT(NT_STATUS_UNSUCCESSFUL);
636 SAM_ADS_PRIVATES *privates = (struct sam_ads_privates *)sam_method->private_data;
637 ADS_STRUCT *ads_struct = privates->ads_struct;
640 SAM_ASSERT(sam_method && access_token && mem_ctx && sid && name && type);
642 ads_status = sam_ads_get_tree_sec_desc(privates, ADS_ROOT_TREE, &my_sd);
643 if (!ADS_ERR_OK(ads_status))
644 return ads_ntstatus(ads_status);
646 ads_status = sam_ads_access_check(privates, my_sd, access_token, GENERIC_RIGHTS_DOMAIN_READ, NULL);
647 if (!ADS_ERR_OK(ads_status))
648 return ads_ntstatus(ads_status);
650 return ads_sid_to_name(ads_struct, mem_ctx, sid, name, type);
653 static NTSTATUS sam_ads_lookup_name(const SAM_METHODS *sam_method, const NT_USER_TOKEN *access_token,
654 const char *name, DOM_SID *sid, enum SID_NAME_USE *type)
656 ADS_STATUS ads_status = ADS_ERROR_NT(NT_STATUS_UNSUCCESSFUL);
657 SAM_ADS_PRIVATES *privates = (struct sam_ads_privates *)sam_method->private_data;
658 ADS_STRUCT *ads_struct = privates->ads_struct;
661 SAM_ASSERT(sam_method && access_token && name && sid && type);
663 ads_status = sam_ads_get_tree_sec_desc(privates, ADS_ROOT_TREE, &my_sd);
664 if (!ADS_ERR_OK(ads_status))
665 return ads_ntstatus(ads_status);
667 ads_status = sam_ads_access_check(privates, my_sd, access_token, GENERIC_RIGHTS_DOMAIN_READ, NULL);
668 if (!ADS_ERR_OK(ads_status))
669 return ads_ntstatus(ads_status);
671 return ads_name_to_sid(ads_struct, name, sid, type);
677 static NTSTATUS sam_ads_update_domain(const SAM_METHODS *sam_method, const SAM_DOMAIN_HANDLE *domain)
679 ADS_STATUS ads_status = ADS_STATUS_NOT_IMPLEMENTED;
680 DEBUG(0,("sam_ads: %s was called!\n",FUNCTION_MACRO));
681 SAM_ASSERT(sam_method);
682 return ads_ntstatus(ads_status);
685 static NTSTATUS sam_ads_get_domain_handle(const SAM_METHODS *sam_method, const NT_USER_TOKEN *access_token,
686 const uint32 access_desired, SAM_DOMAIN_HANDLE **domain)
688 ADS_STATUS ads_status = ADS_STATUS_NOT_IMPLEMENTED;
689 SAM_ADS_PRIVATES *privates = (struct sam_ads_privates *)sam_method->private_data;
690 TALLOC_CTX *mem_ctx = privates->mem_ctx; /*Fix me is this right??? */
691 SAM_DOMAIN_HANDLE *dom_handle = NULL;
696 DEBUG(5,("sam_ads_get_domain_handle: %d\n",__LINE__));
698 SAM_ASSERT(sam_method && access_token && domain);
702 if ((dom_handle = talloc(mem_ctx, sizeof(SAM_DOMAIN_HANDLE))) == NULL) {
703 DEBUG(0,("failed to talloc dom_handle\n"));
704 ads_status = ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
705 return ads_ntstatus(ads_status);
708 ZERO_STRUCTP(dom_handle);
710 dom_handle->mem_ctx = mem_ctx; /*Fix me is this right??? */
711 dom_handle->free_fn = NULL;
712 dom_handle->current_sam_methods = sam_method;
714 /* check if access can be granted as requested */
716 ads_status = sam_ads_get_tree_sec_desc(privates, ADS_ROOT_TREE, &sd);
717 if (!ADS_ERR_OK(ads_status))
718 return ads_ntstatus(ads_status);
720 ads_status = sam_ads_access_check(privates, sd, access_token, access_desired, &acc_granted);
721 if (!ADS_ERR_OK(ads_status))
722 return ads_ntstatus(ads_status);
724 dom_handle->access_granted = acc_granted;
726 /* fill all the values of dom_handle */
727 sid_copy(&dom_handle->private.sid, &sam_method->domain_sid);
728 dom_handle->private.name = smb_xstrdup(sam_method->domain_name);
729 dom_handle->private.servername = "WHOKNOWS"; /* what is the servername */
731 /*Fix me: sam_ads_account_policy_get() return ADS_STATUS! */
732 ads_status = sam_ads_account_policy_get(privates, AP_MAX_PASSWORD_AGE, &tmp_value);
733 if (!ADS_ERR_OK(ads_status)) {
734 DEBUG(4,("sam_ads_account_policy_get failed for max password age. Useing default\n"));
735 tmp_value = MAX_PASSWORD_AGE;
737 unix_to_nt_time_abs(&dom_handle->private.max_passwordage,tmp_value);
739 ads_status = sam_ads_account_policy_get(privates, AP_MIN_PASSWORD_AGE, &tmp_value);
740 if (!ADS_ERR_OK(ads_status)) {
741 DEBUG(4,("sam_ads_account_policy_get failed for min password age. Useing default\n"));
744 unix_to_nt_time_abs(&dom_handle->private.min_passwordage, tmp_value);
746 ads_status = sam_ads_account_policy_get(privates, AP_LOCK_ACCOUNT_DURATION, &tmp_value);
747 if (!ADS_ERR_OK(ads_status)) {
748 DEBUG(4,("sam_ads_account_policy_get failed for lockout duration. Useing default\n"));
751 unix_to_nt_time_abs(&dom_handle->private.lockout_duration, tmp_value);
753 ads_status = sam_ads_account_policy_get(privates, AP_RESET_COUNT_TIME, &tmp_value);
754 if (!ADS_ERR_OK(ads_status)) {
755 DEBUG(4,("sam_ads_account_policy_get failed for time till locout count is reset. Useing default\n"));
758 unix_to_nt_time_abs(&dom_handle->private.reset_count, tmp_value);
760 ads_status = sam_ads_account_policy_get(privates, AP_MIN_PASSWORD_LEN, &tmp_value);
761 if (!ADS_ERR_OK(ads_status)) {
762 DEBUG(4,("sam_ads_account_policy_get failed for min password length. Useing default\n"));
765 dom_handle->private.min_passwordlength = (uint16)tmp_value;
767 ads_status = sam_ads_account_policy_get(privates, AP_PASSWORD_HISTORY, &tmp_value);
768 if (!ADS_ERR_OK(ads_status)) {
769 DEBUG(4,("sam_ads_account_policy_get failed password history. Useing default\n"));
772 dom_handle->private.password_history = (uint16)tmp_value;
774 ads_status = sam_ads_account_policy_get(privates, AP_BAD_ATTEMPT_LOCKOUT, &tmp_value);
775 if (!ADS_ERR_OK(ads_status)) {
776 DEBUG(4,("sam_ads_account_policy_get failed for bad attempts till lockout. Useing default\n"));
779 dom_handle->private.lockout_count = (uint16)tmp_value;
781 ads_status = sam_ads_account_policy_get(privates, AP_TIME_TO_LOGOUT, &tmp_value);
782 if (!ADS_ERR_OK(ads_status)) {
783 DEBUG(4,("sam_ads_account_policy_get failed for force logout. Useing default\n"));
787 ads_status = sam_ads_account_policy_get(privates, AP_USER_MUST_LOGON_TO_CHG_PASS, &tmp_value);
788 if (!ADS_ERR_OK(ads_status)) {
789 DEBUG(4,("sam_ads_account_policy_get failed for user must login to change password. Useing default\n"));
793 /* should the real values of num_accounts, num_groups and num_aliases be retreved?
794 * I think it is to expensive to bother
796 dom_handle->private.num_accounts = 3;
797 dom_handle->private.num_groups = 4;
798 dom_handle->private.num_aliases = 5;
800 *domain = dom_handle;
802 ads_status = ADS_ERROR_NT(NT_STATUS_OK);
803 return ads_ntstatus(ads_status);
807 static NTSTATUS sam_ads_create_account(const SAM_METHODS *sam_method,
808 const NT_USER_TOKEN *access_token, uint32 access_desired,
809 const char *account_name, uint16 acct_ctrl, SAM_ACCOUNT_HANDLE **account)
811 ADS_STATUS ads_status = ADS_STATUS_NOT_IMPLEMENTED;
812 SAM_ADS_PRIVATES *privates = (struct sam_ads_privates *)sam_method->private_data;
816 SAM_ASSERT(sam_method && privates && access_token && account_name && account);
818 ads_status = sam_ads_get_tree_sec_desc(privates, ADS_SUBTREE_USERS, &sd);
819 if (!ADS_ERR_OK(ads_status))
820 return ads_ntstatus(ads_status);
822 ads_status = sam_ads_access_check(privates, sd, access_token, access_desired, &acc_granted);
823 if (!ADS_ERR_OK(ads_status))
824 return ads_ntstatus(ads_status);
826 ads_status = ADS_ERROR_NT(sam_init_account(account));
827 if (!ADS_ERR_OK(ads_status))
828 return ads_ntstatus(ads_status);
830 (*account)->access_granted = acc_granted;
832 return ads_ntstatus(ads_status);
835 static NTSTATUS sam_ads_add_account(const SAM_METHODS *sam_method, const SAM_ACCOUNT_HANDLE *account)
837 ADS_STATUS ads_status = ADS_ERROR(LDAP_NO_MEMORY);
838 SAM_ADS_PRIVATES *privates = (struct sam_ads_privates *)sam_method->private_data;
839 ADS_STRUCT *ads_struct = privates->ads_struct;
840 TALLOC_CTX *mem_ctx = privates->mem_ctx;
847 SAM_ASSERT(sam_method && account);
849 ads_status = ADS_ERROR_NT(sam_get_account_acct_ctrl(account,&acct_ctrl));
850 if (!ADS_ERR_OK(ads_status))
853 if ((acct_ctrl & ACB_WSTRUST)||(acct_ctrl & ACB_SVRTRUST)) {
854 /* Computer account */
855 char *name,*controlstr;
856 char *hostname,*host_upn,*host_spn;
857 const char *objectClass[] = {"top", "person", "organizationalPerson",
858 "user", "computer", NULL};
860 ads_status = ADS_ERROR_NT(sam_get_account_name(account,&name));
861 if (!ADS_ERR_OK(ads_status))
864 if (!(host_upn = talloc_asprintf(mem_ctx, "%s@%s", name, ads_struct->config.realm))) {
865 ads_status = ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
869 if (!(new_dn = talloc_asprintf(mem_ctx, "CN=%s,CN=Computers,%s", hostname,
870 ads_struct->config.bind_path))) {
871 ads_status = ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
875 if (!(controlstr = talloc_asprintf(mem_ctx, "%u", ads_acb2uf(acct_ctrl)))) {
876 ads_status = ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
880 if (!(mods = ads_init_mods(mem_ctx))) {
881 ads_status = ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
885 ads_status = ads_mod_str(mem_ctx, &mods, "cn", hostname);
886 if (!ADS_ERR_OK(ads_status))
888 ads_status = ads_mod_strlist(mem_ctx, &mods, "objectClass", objectClass);
889 if (!ADS_ERR_OK(ads_status))
891 ads_status = ads_mod_str(mem_ctx, &mods, "userPrincipalName", host_upn);
892 if (!ADS_ERR_OK(ads_status))
894 ads_status = ads_mod_str(mem_ctx, &mods, "displayName", hostname);
895 if (!ADS_ERR_OK(ads_status))
897 ads_status = ads_mod_str(mem_ctx, &mods, "sAMAccountName", name);
898 if (!ADS_ERR_OK(ads_status))
900 ads_status = ads_mod_str(mem_ctx, &mods, "userAccountControl", controlstr);
901 if (!ADS_ERR_OK(ads_status))
904 ads_status = ads_mod_str(mem_ctx, &mods, "servicePrincipalName", host_spn);
905 if (!ADS_ERR_OK(ads_status))
907 ads_status = ads_mod_str(mem_ctx, &mods, "dNSHostName", hostname);
908 if (!ADS_ERR_OK(ads_status))
910 ads_status = ads_mod_str(mem_ctx, &mods, "userAccountControl", controlstr);
911 if (!ADS_ERR_OK(ads_status))
913 /* ads_status = ads_mod_str(mem_ctx, &mods, "operatingSystem", "Samba");
914 if (!ADS_ERR_OK(ads_status))
916 *//* ads_status = ads_mod_str(mem_ctx, &mods, "operatingSystemVersion", VERSION);
917 if (!ADS_ERR_OK(ads_status))
920 /* End Computer account */
923 char *upn, *controlstr;
924 char *name, *fullname;
925 const char *objectClass[] = {"top", "person", "organizationalPerson",
928 ads_status = ADS_ERROR_NT(sam_get_account_name(account,&name));
929 if (!ADS_ERR_OK(ads_status))
932 ads_status = ADS_ERROR_NT(sam_get_account_fullname(account,&fullname));
933 if (!ADS_ERR_OK(ads_status))
936 if (!(upn = talloc_asprintf(mem_ctx, "%s@%s", name, ads_struct->config.realm))) {
937 ads_status = ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
941 if (!(new_dn = talloc_asprintf(mem_ctx, "CN=%s,CN=Users,%s", fullname,
942 ads_struct->config.bind_path))) {
943 ads_status = ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
947 if (!(controlstr = talloc_asprintf(mem_ctx, "%u", ads_acb2uf(acct_ctrl)))) {
948 ads_status = ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
952 if (!(mods = ads_init_mods(mem_ctx))) {
953 ads_status = ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
957 ads_status = ads_mod_str(mem_ctx, &mods, "cn", fullname);
958 if (!ADS_ERR_OK(ads_status))
960 ads_status = ads_mod_strlist(mem_ctx, &mods, "objectClass", objectClass);
961 if (!ADS_ERR_OK(ads_status))
963 ads_status = ads_mod_str(mem_ctx, &mods, "userPrincipalName", upn);
964 if (!ADS_ERR_OK(ads_status))
966 ads_status = ads_mod_str(mem_ctx, &mods, "displayName", fullname);
967 if (!ADS_ERR_OK(ads_status))
969 ads_status = ads_mod_str(mem_ctx, &mods, "sAMAccountName", name);
970 if (!ADS_ERR_OK(ads_status))
972 ads_status = ads_mod_str(mem_ctx, &mods, "userAccountControl", controlstr);
973 if (!ADS_ERR_OK(ads_status))
975 }/* End User account */
977 /* Finally at the account */
978 ads_status = ads_gen_add(ads_struct, new_dn, mods);
981 return ads_ntstatus(ads_status);
984 static NTSTATUS sam_ads_update_account(const SAM_METHODS *sam_method, const SAM_ACCOUNT_HANDLE *account)
986 ADS_STATUS ads_status = ADS_STATUS_NOT_IMPLEMENTED;
987 DEBUG(0,("sam_ads: %s was called!\n",FUNCTION_MACRO));
988 SAM_ASSERT(sam_method);
989 return ads_ntstatus(ads_status);
992 static NTSTATUS sam_ads_delete_account(const SAM_METHODS *sam_method, const SAM_ACCOUNT_HANDLE *account)
994 ADS_STATUS ads_status = ADS_STATUS_NOT_IMPLEMENTED;
995 DEBUG(0,("sam_ads: %s was called!\n",FUNCTION_MACRO));
996 SAM_ASSERT(sam_method);
1000 return ads_ntstatus(ads_status);
1003 static NTSTATUS sam_ads_enum_accounts(const SAM_METHODS *sam_method, const NT_USER_TOKEN *access_token, uint16 acct_ctrl, uint32 *account_count, SAM_ACCOUNT_ENUM **accounts)
1005 ADS_STATUS ads_status = ADS_STATUS_NOT_IMPLEMENTED;
1006 DEBUG(0,("sam_ads: %s was called!\n",FUNCTION_MACRO));
1007 SAM_ASSERT(sam_method);
1008 return ads_ntstatus(ads_status);
1012 static NTSTATUS sam_ads_get_account_by_sid(const SAM_METHODS *sam_method, const NT_USER_TOKEN *access_token, const uint32 access_desired, const DOM_SID *account_sid, SAM_ACCOUNT_HANDLE **account)
1014 ADS_STATUS ads_status = ADS_ERROR_NT(NT_STATUS_UNSUCCESSFUL);
1015 SAM_ADS_PRIVATES *privates = (struct sam_ads_privates *)sam_method->private_data;
1016 ADS_STRUCT *ads_struct = privates->ads_struct;
1017 TALLOC_CTX *mem_ctx = privates->mem_ctx;
1018 SEC_DESC *sd = NULL;
1021 SAM_ASSERT(sam_method && privates && ads_struct && access_token && account_sid && account);
1023 ads_status = ADS_ERROR_NT(sam_ads_get_sec_desc(sam_method, access_token, account_sid, &my_sd));
1024 if (!ADS_ERR_OK(ads_status))
1025 return ads_ntstatus(ads_status);
1027 ads_status = sam_ads_access_check(privates, sd, access_token, access_desired, &acc_granted);
1028 if (!ADS_ERR_OK(ads_status))
1029 return ads_ntstatus(ads_status);
1031 ads_status = ADS_ERROR_NT(sam_init_account(account));
1032 if (!ADS_ERR_OK(ads_status))
1033 return ads_ntstatus(ads_status);
1035 (*account)->access_granted = acc_granted;
1037 return ads_ntstatus(ads_status);
1040 static NTSTATUS sam_ads_get_account_by_sid(const SAM_METHODS *sam_method, const NT_USER_TOKEN *access_token, const uint32 access_desired, const DOM_SID *account_sid, SAM_ACCOUNT_HANDLE **account)
1042 ADS_STATUS ads_status = ADS_STATUS_NOT_IMPLEMENTED;
1043 DEBUG(0,("sam_ads: %s was called!\n",FUNCTION_MACRO));
1044 SAM_ASSERT(sam_method);
1045 return ads_ntstatus(ads_status);
1050 static NTSTATUS sam_ads_get_account_by_name(const SAM_METHODS *sam_method, const NT_USER_TOKEN *access_token, const uint32 access_desired, const char *account_name, SAM_ACCOUNT_HANDLE **account)
1052 ADS_STATUS ads_status = ADS_ERROR_NT(NT_STATUS_UNSUCCESSFUL);
1053 SAM_ADS_PRIVATES *privates = (struct sam_ads_privates *)sam_method->private_data;
1054 ADS_STRUCT *ads_struct = privates->ads_struct;
1055 TALLOC_CTX *mem_ctx = privates->mem_ctx;
1056 SEC_DESC *sd = NULL;
1059 SAM_ASSERT(sam_method && privates && ads_struct && access_token && account_name && account);
1061 ads_status = sam_ads_get_tree_sec_desc(privates, ADS_ROOT_TREE, &sd);
1062 if (!ADS_ERR_OK(ads_status))
1063 return ads_ntstatus(ads_status);
1065 ads_status = sam_ads_access_check(privates, sd, access_token, access_desired, &acc_granted);
1066 if (!ADS_ERR_OK(ads_status))
1067 return ads_ntstatus(ads_status);
1069 ads_status = ADS_ERROR_NT(sam_init_account(account));
1070 if (!ADS_ERR_OK(ads_status))
1071 return ads_ntstatus(ads_status);
1073 (*account)->access_granted = acc_granted;
1075 return ads_ntstatus(ads_status);
1078 static NTSTATUS sam_ads_get_account_by_name(const SAM_METHODS *sam_method, const NT_USER_TOKEN *access_token, const uint32 access_desired, const char *account_name, SAM_ACCOUNT_HANDLE **account)
1080 ADS_STATUS ads_status = ADS_STATUS_NOT_IMPLEMENTED;
1081 DEBUG(0,("sam_ads: %s was called!\n",FUNCTION_MACRO));
1082 SAM_ASSERT(sam_method);
1083 return ads_ntstatus(ads_status);
1088 static NTSTATUS sam_ads_create_group(const SAM_METHODS *sam_method, const NT_USER_TOKEN *access_token, uint32 access_desired, const char *group_name, uint16 group_ctrl, SAM_GROUP_HANDLE **group)
1090 ADS_STATUS ads_status = ADS_STATUS_NOT_IMPLEMENTED;
1091 DEBUG(0,("sam_ads: %s was called!\n",FUNCTION_MACRO));
1092 SAM_ASSERT(sam_method);
1093 return ads_ntstatus(ads_status);
1096 static NTSTATUS sam_ads_add_group(const SAM_METHODS *sam_method, const SAM_GROUP_HANDLE *group)
1098 ADS_STATUS ads_status = ADS_STATUS_NOT_IMPLEMENTED;
1099 DEBUG(0,("sam_ads: %s was called!\n",FUNCTION_MACRO));
1100 SAM_ASSERT(sam_method);
1101 return ads_ntstatus(ads_status);
1104 static NTSTATUS sam_ads_update_group(const SAM_METHODS *sam_method, const SAM_GROUP_HANDLE *group)
1106 ADS_STATUS ads_status = ADS_STATUS_NOT_IMPLEMENTED;
1107 DEBUG(0,("sam_ads: %s was called!\n",FUNCTION_MACRO));
1108 SAM_ASSERT(sam_method);
1109 return ads_ntstatus(ads_status);
1112 static NTSTATUS sam_ads_delete_group(const SAM_METHODS *sam_method, const SAM_GROUP_HANDLE *group)
1114 ADS_STATUS ads_status = ADS_STATUS_NOT_IMPLEMENTED;
1115 DEBUG(0,("sam_ads: %s was called!\n",FUNCTION_MACRO));
1116 SAM_ASSERT(sam_method);
1117 return ads_ntstatus(ads_status);
1120 static NTSTATUS sam_ads_enum_groups(const SAM_METHODS *sam_method, const NT_USER_TOKEN *access_token, const uint16 group_ctrl, uint32 *groups_count, SAM_GROUP_ENUM **groups)
1122 ADS_STATUS ads_status = ADS_STATUS_NOT_IMPLEMENTED;
1123 SAM_ADS_PRIVATES *privates = (struct sam_ads_privates *)sam_method->private_data;
1124 ADS_STRUCT *ads_struct = privates->ads_struct;
1125 TALLOC_CTX *mem_ctx = privates->mem_ctx;
1128 char *filter = NULL;
1131 /* get only these LDAP attributes, witch we really need for a group */
1132 const char *group_enum_attrs[] = {"objectSid",
1137 SAM_ASSERT(sam_method && access_token && groups_count && groups);
1141 DEBUG(3,("ads: enum_dom_groups\n"));
1143 FIXME("get only group from the wanted Type!\n");
1144 asprintf(&filter, "(&(objectClass=group)(groupType=%s))", "*");
1145 ads_status = sam_ads_do_search(privates, ads_struct->config.bind_path, LDAP_SCOPE_SUBTREE, filter, group_enum_attrs, &res);
1146 if (!ADS_ERR_OK(ads_status)) {
1147 DEBUG(1,("enum_groups ads_search: %s\n", ads_errstr(ads_status)));
1150 *groups_count = ads_count_replies(ads_struct, res);
1151 if (*groups_count == 0) {
1152 DEBUG(1,("enum_groups: No groups found\n"));
1155 (*groups) = talloc_zero(mem_ctx, (*groups_count) * sizeof(**groups));
1157 ads_status = ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
1160 for (msg = ads_first_entry(ads_struct, res); msg; msg = ads_next_entry(ads_struct, msg)) {
1163 if (!ads_pull_uint32(ads_struct, msg, "groupType", &grouptype)) {
1166 (*groups)->group_ctrl = ads_gtype2gcb(grouptype);
1169 if (!((*groups)->group_name = ads_pull_string(ads_struct, mem_ctx, msg, "sAMAccountName"))) {
1173 if (!((*groups)->group_desc = ads_pull_string(ads_struct, mem_ctx, msg, "description"))) {
1177 if (!ads_pull_sid(ads_struct, msg, "objectSid", &((*groups)->sid))) {
1178 DEBUG(1,("No sid for group %s !?\n", (*groups)->group_name));
1185 (*groups_count) = i;
1187 ads_status = ADS_ERROR_NT(NT_STATUS_OK);
1189 DEBUG(3,("ads enum_dom_groups gave %d entries\n", (*groups_count)));
1191 if (res) ads_msgfree(ads_struct, res);
1193 return ads_ntstatus(ads_status);
1196 static NTSTATUS sam_ads_get_group_by_sid(const SAM_METHODS *sam_method, const NT_USER_TOKEN *access_token, const uint32 access_desired, const DOM_SID *groupsid, SAM_GROUP_HANDLE **group)
1198 ADS_STATUS ads_status = ADS_STATUS_NOT_IMPLEMENTED;
1199 DEBUG(0,("sam_ads: %s was called!\n",FUNCTION_MACRO));
1200 SAM_ASSERT(sam_method);
1201 return ads_ntstatus(ads_status);
1204 static NTSTATUS sam_ads_get_group_by_name(const SAM_METHODS *sam_method, const NT_USER_TOKEN *access_token, const uint32 access_desired, const char *name, SAM_GROUP_HANDLE **group)
1206 ADS_STATUS ads_status = ADS_STATUS_NOT_IMPLEMENTED;
1207 DEBUG(0,("sam_ads: %s was called!\n",FUNCTION_MACRO));
1208 SAM_ASSERT(sam_method);
1209 return ads_ntstatus(ads_status);
1212 static NTSTATUS sam_ads_add_member_to_group(const SAM_METHODS *sam_method, const SAM_GROUP_HANDLE *group, const SAM_GROUP_MEMBER *member)
1214 ADS_STATUS ads_status = ADS_STATUS_NOT_IMPLEMENTED;
1215 DEBUG(0,("sam_ads: %s was called!\n",FUNCTION_MACRO));
1216 SAM_ASSERT(sam_method);
1217 return ads_ntstatus(ads_status);
1220 static NTSTATUS sam_ads_delete_member_from_group(const SAM_METHODS *sam_method, const SAM_GROUP_HANDLE *group, const SAM_GROUP_MEMBER *member)
1222 ADS_STATUS ads_status = ADS_STATUS_NOT_IMPLEMENTED;
1223 DEBUG(0,("sam_ads: %s was called!\n",FUNCTION_MACRO));
1224 SAM_ASSERT(sam_method);
1225 return ads_ntstatus(ads_status);
1228 static NTSTATUS sam_ads_enum_groupmembers(const SAM_METHODS *sam_method, const SAM_GROUP_HANDLE *group, uint32 *members_count, SAM_GROUP_MEMBER **members)
1230 ADS_STATUS ads_status = ADS_STATUS_NOT_IMPLEMENTED;
1231 DEBUG(0,("sam_ads: %s was called!\n",FUNCTION_MACRO));
1232 SAM_ASSERT(sam_method);
1233 return ads_ntstatus(ads_status);
1236 static NTSTATUS sam_ads_get_groups_of_sid(const SAM_METHODS *sam_method, const NT_USER_TOKEN *access_token, const DOM_SID **sids, const uint16 group_ctrl, uint32 *group_count, SAM_GROUP_ENUM **groups)
1238 ADS_STATUS ads_status = ADS_STATUS_NOT_IMPLEMENTED;
1239 DEBUG(0,("sam_ads: %s was called!\n",FUNCTION_MACRO));
1240 SAM_ASSERT(sam_method);
1241 return ads_ntstatus(ads_status);
1244 /**********************************
1245 Free our private data
1246 ***********************************/
1247 static void sam_ads_free_private_data(void **vp)
1249 SAM_ADS_PRIVATES **sam_ads_state = (SAM_ADS_PRIVATES **)vp;
1251 if ((*sam_ads_state)->ads_struct->ld) {
1252 ldap_unbind((*sam_ads_state)->ads_struct->ld);
1255 ads_destroy(&((*sam_ads_state)->ads_struct));
1257 talloc_destroy((*sam_ads_state)->mem_ctx);
1258 FIXME("maybe we must free some other stuff here\n");
1260 *sam_ads_state = NULL;
1265 /*****************************************************
1266 Init the ADS SAM backend
1267 ******************************************************/
1268 NTSTATUS sam_init_ads(SAM_METHODS *sam_method, const char *module_params)
1270 ADS_STATUS ads_status;
1271 SAM_ADS_PRIVATES *sam_ads_state;
1272 TALLOC_CTX *mem_ctx;
1274 SAM_ASSERT(sam_method && sam_method->parent);
1276 mem_ctx = sam_method->parent->mem_ctx;
1278 /* Here the SAM API functions of the sam_ads module */
1282 sam_method->sam_get_sec_desc = sam_ads_get_sec_desc;
1283 sam_method->sam_set_sec_desc = sam_ads_set_sec_desc;
1285 sam_method->sam_lookup_sid = sam_ads_lookup_sid;
1286 sam_method->sam_lookup_name = sam_ads_lookup_name;
1290 sam_method->sam_update_domain = sam_ads_update_domain;
1291 sam_method->sam_get_domain_handle = sam_ads_get_domain_handle;
1295 sam_method->sam_create_account = sam_ads_create_account;
1296 sam_method->sam_add_account = sam_ads_add_account;
1297 sam_method->sam_update_account = sam_ads_update_account;
1298 sam_method->sam_delete_account = sam_ads_delete_account;
1299 sam_method->sam_enum_accounts = sam_ads_enum_accounts;
1301 sam_method->sam_get_account_by_sid = sam_ads_get_account_by_sid;
1302 sam_method->sam_get_account_by_name = sam_ads_get_account_by_name;
1306 sam_method->sam_create_group = sam_ads_create_group;
1307 sam_method->sam_add_group = sam_ads_add_group;
1308 sam_method->sam_update_group = sam_ads_update_group;
1309 sam_method->sam_delete_group = sam_ads_delete_group;
1310 sam_method->sam_enum_groups = sam_ads_enum_groups;
1311 sam_method->sam_get_group_by_sid = sam_ads_get_group_by_sid;
1312 sam_method->sam_get_group_by_name = sam_ads_get_group_by_name;
1314 sam_method->sam_add_member_to_group = sam_ads_add_member_to_group;
1315 sam_method->sam_delete_member_from_group = sam_ads_delete_member_from_group;
1316 sam_method->sam_enum_groupmembers = sam_ads_enum_groupmembers;
1318 sam_method->sam_get_groups_of_sid = sam_ads_get_groups_of_sid;
1320 sam_ads_state = talloc_zero(mem_ctx, sizeof(SAM_ADS_PRIVATES));
1321 if (!sam_ads_state) {
1322 DEBUG(0, ("talloc() failed for sam_ads private_data!\n"));
1323 return NT_STATUS_NO_MEMORY;
1326 if (!(sam_ads_state->mem_ctx = talloc_init("sam_ads_method"))) {
1327 DEBUG(0, ("talloc_init() failed for sam_ads_state->mem_ctx\n"));
1328 return NT_STATUS_NO_MEMORY;
1331 sam_ads_state->ads_bind_dn = talloc_strdup(sam_ads_state->mem_ctx, lp_parm_const_string(GLOBAL_SECTION_SNUM,"sam_ads","bind as", ""));
1332 sam_ads_state->ads_bind_pw = talloc_strdup(sam_ads_state->mem_ctx, lp_parm_const_string(GLOBAL_SECTION_SNUM,"sam_ads","bind pw", ""));
1334 sam_ads_state->bind_plaintext = lp_parm_bool(GLOBAL_SECTION_SNUM, "sam_ads", "plaintext bind" , True);
1336 if (!sam_ads_state->ads_bind_dn || !sam_ads_state->ads_bind_pw) {
1337 DEBUG(0, ("talloc_strdup() failed for bind dn or password\n"));
1338 return NT_STATUS_NO_MEMORY;
1341 /* Maybe we should not check the result here? Server down on startup? */
1343 if (module_params && *module_params) {
1344 sam_ads_state->ldap_uri = talloc_strdup(sam_ads_state->mem_ctx, module_params);
1345 if (!sam_ads_state->ldap_uri) {
1346 DEBUG(0, ("talloc_strdup() failed for bind dn or password\n"));
1347 return NT_STATUS_NO_MEMORY;
1350 sam_ads_state->ldap_uri = "ldapi://";
1353 ads_status = sam_ads_cached_connection(sam_ads_state);
1354 if (!ADS_ERR_OK(ads_status)) {
1355 return ads_ntstatus(ads_status);
1358 sam_method->private_data = sam_ads_state;
1359 sam_method->free_private_data = sam_ads_free_private_data;
1361 sam_ads_debug_level = debug_add_class("sam_ads");
1362 if (sam_ads_debug_level == -1) {
1363 sam_ads_debug_level = DBGC_ALL;
1364 DEBUG(0, ("sam_ads: Couldn't register custom debugging class!\n"));
1365 } else DEBUG(2, ("sam_ads: Debug class number of 'sam_ads': %d\n", sam_ads_debug_level));
1367 DEBUG(5, ("Initializing sam_ads\n"));
1369 DEBUG(10, ("Module Parameters for Domain %s[%s]: %s\n", sam_method->domain_name, sam_method->domain_name, module_params));
1370 return NT_STATUS_OK;
1373 #else /* HAVE_LDAP */
1374 void sam_ads_dummy(void)
1376 DEBUG(0,("sam_ads: not supported!\n"));
1378 #endif /* HAVE_LDAP */