From b2edf254eda92f775e7d3d9b6793b4d77f9000b6 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 17 Aug 2002 17:00:51 +0000 Subject: sync 3.0 branch with head (This used to be commit 3928578b52cfc949be5e0ef444fce1558d75f290) --- source3/passdb/passdb.c | 158 +++++++++++++++++++++--------------- source3/passdb/pdb_get_set.c | 11 ++- source3/passdb/pdb_interface.c | 6 +- source3/passdb/pdb_ldap.c | 179 +++++++++++++++++++++++++++++++---------- source3/passdb/pdb_nisplus.c | 16 ++-- source3/passdb/pdb_smbpasswd.c | 4 +- source3/passdb/pdb_tdb.c | 7 +- source3/passdb/pdb_unix.c | 29 +++++-- source3/passdb/secrets.c | 62 +++++++++++++- source3/passdb/util_sam_sid.c | 3 + 10 files changed, 336 insertions(+), 139 deletions(-) (limited to 'source3/passdb') diff --git a/source3/passdb/passdb.c b/source3/passdb/passdb.c index 4e3d558e98..a9c6f0729b 100644 --- a/source3/passdb/passdb.c +++ b/source3/passdb/passdb.c @@ -157,6 +157,12 @@ NTSTATUS pdb_fill_sam_pw(SAM_ACCOUNT *sam_account, const struct passwd *pwd) { GROUP_MAP map; + const char *guest_account = lp_guestaccount(); + if (!(guest_account && *guest_account)) { + DEBUG(1, ("NULL guest account!?!?\n")); + return NT_STATUS_UNSUCCESSFUL; + } + if (!pwd) { return NT_STATUS_UNSUCCESSFUL; } @@ -183,24 +189,36 @@ NTSTATUS pdb_fill_sam_pw(SAM_ACCOUNT *sam_account, const struct passwd *pwd) -- abartlet 11-May-02 */ - if (!pdb_set_user_sid_from_rid(sam_account, - fallback_pdb_uid_to_user_rid(pwd->pw_uid))) { - DEBUG(0,("Can't set User SID from RID!\n")); - return NT_STATUS_INVALID_PARAMETER; - } - /* call the mapping code here */ - if(get_group_map_from_gid(pwd->pw_gid, &map, MAPPING_WITHOUT_PRIV)) { - if (!pdb_set_group_sid(sam_account,&map.sid)){ - DEBUG(0,("Can't set Group SID!\n")); - return NT_STATUS_INVALID_PARAMETER; + /* Ensure this *must* be set right */ + if (strcmp(pwd->pw_name, guest_account) == 0) { + if (!pdb_set_user_sid_from_rid(sam_account, DOMAIN_USER_RID_GUEST)) { + return NT_STATUS_UNSUCCESSFUL; } - } - else { - if (!pdb_set_group_sid_from_rid(sam_account,pdb_gid_to_group_rid(pwd->pw_gid))) { - DEBUG(0,("Can't set Group SID\n")); + if (!pdb_set_group_sid_from_rid(sam_account, DOMAIN_GROUP_RID_GUESTS)) { + return NT_STATUS_UNSUCCESSFUL; + } + } else { + + if (!pdb_set_user_sid_from_rid(sam_account, + fallback_pdb_uid_to_user_rid(pwd->pw_uid))) { + DEBUG(0,("Can't set User SID from RID!\n")); return NT_STATUS_INVALID_PARAMETER; } + + /* call the mapping code here */ + if(get_group_map_from_gid(pwd->pw_gid, &map, MAPPING_WITHOUT_PRIV)) { + if (!pdb_set_group_sid(sam_account,&map.sid)){ + DEBUG(0,("Can't set Group SID!\n")); + return NT_STATUS_INVALID_PARAMETER; + } + } + else { + if (!pdb_set_group_sid_from_rid(sam_account,pdb_gid_to_group_rid(pwd->pw_gid))) { + DEBUG(0,("Can't set Group SID\n")); + return NT_STATUS_INVALID_PARAMETER; + } + } } /* check if this is a user account or a machine account */ @@ -528,6 +546,9 @@ BOOL pdb_rid_is_user(uint32 rid) * such that it can be identified as either a user, group etc * type. there are 5 such categories, and they are documented. */ + /* However, they are not in the RID, just somthing you can query + seperatly. Sorry luke :-) */ + if(pdb_rid_is_well_known(rid)) { /* * The only well known user RIDs are DOMAIN_USER_RID_ADMIN @@ -571,14 +592,6 @@ BOOL local_lookup_sid(DOM_SID *sid, char *name, enum SID_NAME_USE *psid_name_use fstrcpy(name, "Administrator"); } return True; - - } else if (rid == DOMAIN_USER_RID_GUEST) { - char *p = lp_guestaccount(); - *psid_name_use = SID_NAME_USER; - if(!next_token(&p, name, NULL, sizeof(fstring))) - fstrcpy(name, "Guest"); - return True; - } /* @@ -594,6 +607,7 @@ BOOL local_lookup_sid(DOM_SID *sid, char *name, enum SID_NAME_USE *psid_name_use } /* This now does the 'generic' mapping in pdb_unix */ + /* 'guest' is also handled there */ if (pdb_getsampwsid(sam_account, sid)) { fstrcpy(name, pdb_get_username(sam_account)); *psid_name_use = SID_NAME_USER; @@ -716,15 +730,9 @@ BOOL local_lookup_name(const char *c_user, DOM_SID *psid, enum SID_NAME_USE *psi /* check if it's a mapped group */ if (get_group_map_from_ntname(user, &map, MAPPING_WITHOUT_PRIV)) { - if (map.gid!=-1) { - /* yes it's a mapped group to a valid unix group */ - sid_copy(&local_sid, &map.sid); - *psid_name_use = map.sid_name_use; - } - else { - /* it's a correct name but not mapped so it points to nothing*/ - return False; - } + /* yes it's a mapped group */ + sid_copy(&local_sid, &map.sid); + *psid_name_use = map.sid_name_use; } else { /* it's not a mapped group */ grp = getgrnam(user); @@ -777,6 +785,8 @@ DOM_SID *local_uid_to_sid(DOM_SID *psid, uid_t uid) if (pdb_getsampwnam(sam_user, pass->pw_name)) { sid_copy(psid, pdb_get_user_sid(sam_user)); + } else if (strcmp(pass->pw_name, lp_guestaccount()) == 0) { + sid_append_rid(psid, DOMAIN_USER_RID_GUEST); } else { sid_append_rid(psid, fallback_pdb_uid_to_user_rid(uid)); } @@ -802,25 +812,13 @@ DOM_SID *local_uid_to_sid(DOM_SID *psid, uid_t uid) Convert a SID to uid - locally. ****************************************************************************/ -BOOL local_sid_to_uid(uid_t *puid, DOM_SID *psid, enum SID_NAME_USE *name_type) +BOOL local_sid_to_uid(uid_t *puid, const DOM_SID *psid, enum SID_NAME_USE *name_type) { - DOM_SID dom_sid; - uint32 rid; fstring str; SAM_ACCOUNT *sam_user = NULL; *name_type = SID_NAME_UNKNOWN; - sid_copy(&dom_sid, psid); - sid_split_rid(&dom_sid, &rid); - - /* - * We can only convert to a uid if this is our local - * Domain SID (ie. we are the controling authority). - */ - if (!sid_equal(get_global_sam_sid(), &dom_sid)) - return False; - if (NT_STATUS_IS_ERR(pdb_init_sam(&sam_user))) return False; @@ -832,12 +830,37 @@ BOOL local_sid_to_uid(uid_t *puid, DOM_SID *psid, enum SID_NAME_USE *name_type) } DEBUG(10,("local_sid_to_uid: SID %s -> uid (%u) (%s).\n", sid_to_string( str, psid), (unsigned int)*puid, pdb_get_username(sam_user))); - } else { - DEBUG(5,("local_sid_to_uid: SID %s not mapped becouse RID was not found in passdb.\n", sid_to_string( str, psid))); pdb_free_sam(&sam_user); - return False; + } else { + + DOM_SID dom_sid; + uint32 rid; + GROUP_MAP map; + + pdb_free_sam(&sam_user); + + if (get_group_map_from_sid(*psid, &map, MAPPING_WITHOUT_PRIV)) { + DEBUG(3, ("local_sid_to_uid: SID '%s' is a group, not a user... \n", sid_to_string(str, psid))); + /* It's a group, not a user... */ + return False; + } + + sid_copy(&dom_sid, psid); + if (!sid_peek_check_rid(get_global_sam_sid(), psid, &rid)) { + DEBUG(3, ("sid_peek_rid failed - sid '%s' is not in our domain\n", sid_to_string(str, psid))); + return False; + } + + if (!pdb_rid_is_user(rid)) { + DEBUG(3, ("local_sid_to_uid: sid '%s' cannot be mapped to a uid algorithmicly becouse it is a group\n", sid_to_string(str, psid))); + return False; + } + + *puid = fallback_pdb_user_rid_to_uid(rid); + + DEBUG(5,("local_sid_to_uid: SID %s algorithmicly mapped to %ld mapped becouse SID was not found in passdb.\n", + sid_to_string(str, psid), (signed long int)(*puid))); } - pdb_free_sam(&sam_user); *name_type = SID_NAME_USER; @@ -868,18 +891,13 @@ DOM_SID *local_gid_to_sid(DOM_SID *psid, gid_t gid) Convert a SID to gid - locally. ****************************************************************************/ -BOOL local_sid_to_gid(gid_t *pgid, DOM_SID *psid, enum SID_NAME_USE *name_type) +BOOL local_sid_to_gid(gid_t *pgid, const DOM_SID *psid, enum SID_NAME_USE *name_type) { - DOM_SID dom_sid; - uint32 rid; fstring str; GROUP_MAP map; *name_type = SID_NAME_UNKNOWN; - sid_copy(&dom_sid, psid); - sid_split_rid(&dom_sid, &rid); - /* * We can only convert to a gid if this is our local * Domain SID (ie. we are the controling authority). @@ -887,35 +905,45 @@ BOOL local_sid_to_gid(gid_t *pgid, DOM_SID *psid, enum SID_NAME_USE *name_type) * Or in the Builtin SID too. JFM, 11/30/2001 */ - if (!sid_equal(get_global_sam_sid(), &dom_sid)) - return False; - if (get_group_map_from_sid(*psid, &map, MAPPING_WITHOUT_PRIV)) { /* the SID is in the mapping table but not mapped */ if (map.gid==-1) return False; - if (!sid_peek_check_rid(get_global_sam_sid(), &map.sid, &rid)){ - DEBUG(0,("local_sid_to_gid: sid_peek_check_rid return False! SID: %s\n", - sid_string_static(&map.sid))); - return False; - } *pgid = map.gid; *name_type = map.sid_name_use; - DEBUG(10,("local_sid_to_gid: mapped SID %s (%s) -> gid (%u).\n", sid_to_string( str, psid), + DEBUG(10,("local_sid_to_gid: mapped SID %s (%s) -> gid (%u).\n", + sid_to_string( str, psid), map.nt_name, (unsigned int)*pgid)); } else { - if (pdb_rid_is_user(rid)) + uint32 rid; + SAM_ACCOUNT *sam_user = NULL; + if (NT_STATUS_IS_ERR(pdb_init_sam(&sam_user))) + return False; + + if (pdb_getsampwsid(sam_user, psid)) { return False; + pdb_free_sam(&sam_user); + } + + pdb_free_sam(&sam_user); + if (!sid_peek_check_rid(get_global_sam_sid(), psid, &rid)) { + DEBUG(3, ("sid_peek_rid failed - sid '%s' is not in our domain\n", sid_to_string(str, psid))); + return False; + } + + if (pdb_rid_is_user(rid)) + return False; + *pgid = pdb_group_rid_to_gid(rid); *name_type = SID_NAME_ALIAS; DEBUG(10,("local_sid_to_gid: SID %s -> gid (%u).\n", sid_to_string( str, psid), (unsigned int)*pgid)); } - + return True; } diff --git a/source3/passdb/pdb_get_set.c b/source3/passdb/pdb_get_set.c index dff4b40f4d..2da6de7270 100644 --- a/source3/passdb/pdb_get_set.c +++ b/source3/passdb/pdb_get_set.c @@ -250,7 +250,7 @@ const char* pdb_get_unix_homedir (const SAM_ACCOUNT *sampass) return (NULL); } -const char* pdb_get_dirdrive (const SAM_ACCOUNT *sampass) +const char* pdb_get_dir_drive (const SAM_ACCOUNT *sampass) { if (sampass) return (sampass->private.dir_drive); @@ -1028,15 +1028,14 @@ BOOL pdb_set_pass_changed_now (SAM_ACCOUNT *sampass) if (!pdb_set_pass_last_set_time (sampass, time(NULL))) return False; - account_policy_get(AP_MAX_PASSWORD_AGE, &expire); - - if (expire==(uint32)-1) { + if (!account_policy_get(AP_MAX_PASSWORD_AGE, &expire) + || (expire==(uint32)-1)) { if (!pdb_set_pass_must_change_time (sampass, get_time_t_max(), False)) return False; } else { if (!pdb_set_pass_must_change_time (sampass, - pdb_get_pass_last_set_time(sampass) - + expire, True)) + pdb_get_pass_last_set_time(sampass) + + expire, True)) return False; } diff --git a/source3/passdb/pdb_interface.c b/source3/passdb/pdb_interface.c index 3b0f54b2b3..f311223d77 100644 --- a/source3/passdb/pdb_interface.c +++ b/source3/passdb/pdb_interface.c @@ -123,7 +123,7 @@ static BOOL context_getsampwnam(struct pdb_context *context, SAM_ACCOUNT *sam_ac return False; } -static BOOL context_getsampwsid(struct pdb_context *context, SAM_ACCOUNT *sam_acct, DOM_SID *sid) +static BOOL context_getsampwsid(struct pdb_context *context, SAM_ACCOUNT *sam_acct, const DOM_SID *sid) { struct pdb_methods *curmethods; if ((!context)) { @@ -353,7 +353,7 @@ NTSTATUS make_pdb_context_list(struct pdb_context **context, char **selected) NTSTATUS make_pdb_context_string(struct pdb_context **context, const char *selected) { NTSTATUS ret; - char **newsel = str_list_make(selected); + char **newsel = str_list_make(selected, NULL); ret = make_pdb_context_list(context, newsel); str_list_free(&newsel); return ret; @@ -434,7 +434,7 @@ BOOL pdb_getsampwnam(SAM_ACCOUNT *sam_acct, const char *username) return pdb_context->pdb_getsampwnam(pdb_context, sam_acct, username); } -BOOL pdb_getsampwsid(SAM_ACCOUNT *sam_acct, DOM_SID *sid) +BOOL pdb_getsampwsid(SAM_ACCOUNT *sam_acct, const DOM_SID *sid) { struct pdb_context *pdb_context = pdb_get_static_context(False); diff --git a/source3/passdb/pdb_ldap.c b/source3/passdb/pdb_ldap.c index 24eb7b9dc1..f82cb4488f 100644 --- a/source3/passdb/pdb_ldap.c +++ b/source3/passdb/pdb_ldap.c @@ -1,11 +1,12 @@ /* Unix SMB/CIFS implementation. LDAP protocol helper functions for SAMBA - Copyright (C) Gerald Carter 2001 - Copyright (C) Shahms King 2001 - Copyright (C) Jean François Micouleau 1998 - Copyright (C) Andrew Bartlett 2002 - + Copyright (C) Jean François Micouleau 1998 + Copyright (C) Gerald Carter 2001 + Copyright (C) Shahms King 2001 + Copyright (C) Andrew Bartlett 2002 + Copyright (C) Stefan (metze) Metzmacher 2002 + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or @@ -70,8 +71,14 @@ struct ldapsam_privates { uint32 low_nua_rid; uint32 high_nua_rid; + + char *bind_dn; + char *bind_secret; }; + +static struct ldapsam_privates *static_ldap_state; + static uint32 ldapsam_get_next_available_nua_rid(struct ldapsam_privates *ldap_state); /******************************************************************* @@ -153,11 +160,13 @@ static const char *attr[] = {"uid", "pwdLastSet", "logonTime", static BOOL ldapsam_open_connection (struct ldapsam_privates *ldap_state, LDAP ** ldap_struct) { + int version; + if (geteuid() != 0) { DEBUG(0, ("ldap_open_connection: cannot access LDAP when not root..\n")); return False; } - + #if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000) DEBUG(10, ("ldapsam_open_connection: %s\n", ldap_state->uri)); @@ -165,6 +174,16 @@ static BOOL ldapsam_open_connection (struct ldapsam_privates *ldap_state, LDAP * DEBUG(0, ("ldap_initialize: %s\n", strerror(errno))); return (False); } + + if (ldap_get_option(*ldap_struct, LDAP_OPT_PROTOCOL_VERSION, &version) == LDAP_OPT_SUCCESS) + { + if (version != LDAP_VERSION3) + { + version = LDAP_VERSION3; + ldap_set_option (*ldap_struct, LDAP_OPT_PROTOCOL_VERSION, &version); + } + } + #else /* Parse the string manually */ @@ -173,7 +192,6 @@ static BOOL ldapsam_open_connection (struct ldapsam_privates *ldap_state, LDAP * int rc; int tls = LDAP_OPT_X_TLS_HARD; int port = 0; - int version; fstring protocol; fstring host; const char *p = ldap_state->uri; @@ -252,42 +270,91 @@ static BOOL ldapsam_open_connection (struct ldapsam_privates *ldap_state, LDAP * /******************************************************************* - Add a rebind function for authenticated referrals + a rebind function for authenticated referrals + This version takes a void* that we can shove useful stuff in :-) ******************************************************************/ -static int rebindproc (LDAP *ldap_struct, char **whop, char **credp, - int *method, int freeit ) +static int rebindproc_with_state (LDAP * ld, char **whop, char **credp, + int *methodp, int freeit, void *arg) { - int rc; - char *ldap_dn; - char *ldap_secret; + struct ldapsam_privates *ldap_state = arg; /** @TODO Should we be doing something to check what servers we rebind to? Could we get a referral to a machine that we don't want to give our username and password to? */ - if (freeit != 0) - { - - if (!fetch_ldapsam_pw(&ldap_dn, &ldap_secret)) - { - DEBUG(0, ("ldap_connect_system: Failed to retrieve password from secrets.tdb\n")); - return LDAP_OPERATIONS_ERROR; /* No idea what to return */ - } - + if (freeit) { + SAFE_FREE(*whop); + memset(*credp, '\0', strlen(*credp)); + SAFE_FREE(*credp); + } else { DEBUG(5,("ldap_connect_system: Rebinding as \"%s\"\n", - ldap_dn)); - - rc = ldap_simple_bind_s(ldap_struct, ldap_dn, ldap_secret); - - SAFE_FREE(ldap_dn); - SAFE_FREE(ldap_secret); + ldap_state->bind_dn)); - return rc; + *whop = strdup(ldap_state->bind_dn); + if (!*whop) { + return LDAP_NO_MEMORY; + } + *credp = strdup(ldap_state->bind_secret); + if (!*credp) { + SAFE_FREE(*whop); + return LDAP_NO_MEMORY; + } + *methodp = LDAP_AUTH_SIMPLE; } return 0; } +/******************************************************************* + a rebind function for authenticated referrals + This version takes a void* that we can shove useful stuff in :-) + and actually does the connection. +******************************************************************/ + +static int rebindproc_connect_with_state (LDAP *ldap_struct, + LDAP_CONST char *url, + ber_tag_t request, + ber_int_t msgid, void *arg) +{ + struct ldapsam_privates *ldap_state = arg; + int rc; + DEBUG(5,("ldap_connect_system: Rebinding as \"%s\"\n", + ldap_state->bind_dn)); + + /** @TODO Should we be doing something to check what servers we rebind to? + Could we get a referral to a machine that we don't want to give our + username and password to? */ + + rc = ldap_simple_bind_s(ldap_struct, ldap_state->bind_dn, ldap_state->bind_secret); + + return rc; +} + +/******************************************************************* + Add a rebind function for authenticated referrals +******************************************************************/ + +static int rebindproc (LDAP *ldap_struct, char **whop, char **credp, + int *method, int freeit ) +{ + return rebindproc_with_state(ldap_struct, whop, credp, + method, freeit, static_ldap_state); + +} + +/******************************************************************* + a rebind function for authenticated referrals + this also does the connection, but no void*. +******************************************************************/ + +static int rebindproc_connect (LDAP * ld, LDAP_CONST char *url, int request, + ber_int_t msgid) +{ + return rebindproc_connect_with_state(ld, url, (ber_tag_t)request, msgid, + static_ldap_state); +} + + /******************************************************************* connect to the ldap server under system privilege. ******************************************************************/ @@ -297,6 +364,10 @@ static BOOL ldapsam_connect_system(struct ldapsam_privates *ldap_state, LDAP * l char *ldap_dn; char *ldap_secret; + /* The rebind proc needs this *HACK*. We are not multithreaded, so + this will work, but it's not nice. */ + static_ldap_state = ldap_state; + /* get the password */ if (!fetch_ldapsam_pw(&ldap_dn, &ldap_secret)) { @@ -304,19 +375,32 @@ static BOOL ldapsam_connect_system(struct ldapsam_privates *ldap_state, LDAP * l return False; } + ldap_state->bind_dn = ldap_dn; + ldap_state->bind_secret = ldap_secret; + /* removed the sasl_bind_s "EXTERNAL" stuff, as my testsuite (OpenLDAP) doesnt' seem to support it */ DEBUG(10,("ldap_connect_system: Binding to ldap server as \"%s\"\n", ldap_dn)); - - ldap_set_rebind_proc(ldap_struct, (LDAP_REBIND_PROC *)(&rebindproc)); +#if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000) +# if LDAP_SET_REBIND_PROC_ARGS == 2 + ldap_set_rebind_proc(ldap_struct, &rebindproc_connect); +# endif +# if LDAP_SET_REBIND_PROC_ARGS == 3 + ldap_set_rebind_proc(ldap_struct, &rebindproc_connect_with_state, (void *)ldap_state); +# endif +#else +# if LDAP_SET_REBIND_PROC_ARGS == 2 + ldap_set_rebind_proc(ldap_struct, &rebindproc); +# endif +# if LDAP_SET_REBIND_PROC_ARGS == 3 + ldap_set_rebind_proc(ldap_struct, &rebindproc_with_state, (void *)ldap_state); +# endif +#endif rc = ldap_simple_bind_s(ldap_struct, ldap_dn, ldap_secret); - SAFE_FREE(ldap_dn); - SAFE_FREE(ldap_secret); - if (rc != LDAP_SUCCESS) { DEBUG(0, ("Bind failed: %s\n", ldap_err2string(rc))); @@ -756,18 +840,20 @@ static BOOL init_sam_from_ldap (struct ldapsam_privates *ldap_state, /* leave as default */ } else { pdb_gethexpwd(temp, smblmpwd); - memset((char *)temp, '\0', sizeof(temp)); + memset((char *)temp, '\0', strlen(temp)+1); if (!pdb_set_lanman_passwd(sampass, smblmpwd)) return False; + ZERO_STRUCT(smblmpwd); } if (!get_single_attribute (ldap_struct, entry, "ntPassword", temp)) { /* leave as default */ } else { pdb_gethexpwd(temp, smbntpwd); - memset((char *)temp, '\0', sizeof(temp)); + memset((char *)temp, '\0', strlen(temp)+1); if (!pdb_set_nt_passwd(sampass, smbntpwd)) return False; + ZERO_STRUCT(smbntpwd); } if (!get_single_attribute (ldap_struct, entry, "acctFlags", temp)) { @@ -880,7 +966,7 @@ static BOOL init_ldap_from_sam (struct ldapsam_privates *ldap_state, make_a_mod(mods, ldap_op, "smbHome", pdb_get_homedir(sampass)); if (IS_SAM_SET(sampass, FLAG_SAM_DRIVE)) - make_a_mod(mods, ldap_op, "homeDrive", pdb_get_dirdrive(sampass)); + make_a_mod(mods, ldap_op, "homeDrive", pdb_get_dir_drive(sampass)); if (IS_SAM_SET(sampass, FLAG_SAM_LOGONSCRIPT)) make_a_mod(mods, ldap_op, "scriptPath", pdb_get_logon_script(sampass)); @@ -1153,6 +1239,10 @@ static BOOL ldapsam_getsampwent(struct pdb_methods *my_methods, SAM_ACCOUNT * us struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data; BOOL ret = False; + /* The rebind proc needs this *HACK*. We are not multithreaded, so + this will work, but it's not nice. */ + static_ldap_state = ldap_state; + while (!ret) { if (!ldap_state->entry) return False; @@ -1203,7 +1293,7 @@ static BOOL ldapsam_getsampwnam(struct pdb_methods *my_methods, SAM_ACCOUNT * us if (entry) { if (!init_sam_from_ldap(ldap_state, user, ldap_struct, entry)) { - DEBUG(0,("ldapsam_getsampwnam: init_sam_from_ldap failed!\n")); + DEBUG(1,("ldapsam_getsampwnam: init_sam_from_ldap failed for user '%s'!\n", sname)); ldap_msgfree(result); ldap_unbind(ldap_struct); return False; @@ -1247,7 +1337,7 @@ static BOOL ldapsam_getsampwrid(struct pdb_methods *my_methods, SAM_ACCOUNT * us if (ldap_count_entries(ldap_struct, result) < 1) { - DEBUG(0, + DEBUG(4, ("We don't find this rid [%i] count=%d\n", rid, ldap_count_entries(ldap_struct, result))); ldap_unbind(ldap_struct); @@ -1258,7 +1348,7 @@ static BOOL ldapsam_getsampwrid(struct pdb_methods *my_methods, SAM_ACCOUNT * us if (entry) { if (!init_sam_from_ldap(ldap_state, user, ldap_struct, entry)) { - DEBUG(0,("ldapsam_getsampwrid: init_sam_from_ldap failed!\n")); + DEBUG(1,("ldapsam_getsampwrid: init_sam_from_ldap failed!\n")); ldap_msgfree(result); ldap_unbind(ldap_struct); return False; @@ -1275,7 +1365,7 @@ static BOOL ldapsam_getsampwrid(struct pdb_methods *my_methods, SAM_ACCOUNT * us } } -static BOOL ldapsam_getsampwsid(struct pdb_methods *my_methods, SAM_ACCOUNT * user, DOM_SID *sid) +static BOOL ldapsam_getsampwsid(struct pdb_methods *my_methods, SAM_ACCOUNT * user, const DOM_SID *sid) { uint32 rid; if (!sid_peek_check_rid(get_global_sam_sid(), sid, &rid)) @@ -1530,6 +1620,13 @@ static void free_private_data(void **vp) ldap_unbind((*ldap_state)->ldap_struct); } + if ((*ldap_state)->bind_secret) { + memset((*ldap_state)->bind_secret, '\0', strlen((*ldap_state)->bind_secret)); + } + + SAFE_FREE((*ldap_state)->bind_dn); + SAFE_FREE((*ldap_state)->bind_secret); + *ldap_state = NULL; /* No need to free any further, as it is talloc()ed */ diff --git a/source3/passdb/pdb_nisplus.c b/source3/passdb/pdb_nisplus.c index 9c5b2e1171..2d37c3b8fb 100644 --- a/source3/passdb/pdb_nisplus.c +++ b/source3/passdb/pdb_nisplus.c @@ -735,17 +735,17 @@ static BOOL init_nisp_from_sam(nis_object *obj, const SAM_ACCOUNT *sampass, /* dir_drive */ /* must support set, unset and change */ - if( (pdb_get_dirdrive(sampass) && + if( (pdb_get_dir_drive(sampass) && !ENTRY_VAL(old, NPF_DIR_DRIVE)) || (ENTRY_VAL(old, NPF_DIR_DRIVE) && - !pdb_get_dirdrive(sampass)) || + !pdb_get_dir_drive(sampass)) || (ENTRY_VAL(old, NPF_DIR_DRIVE) && - pdb_get_dirdrive(sampass) && + pdb_get_dir_drive(sampass) && strcmp( ENTRY_VAL(old, NPF_DIR_DRIVE), - pdb_get_dirdrive(sampass)))) { + pdb_get_dir_drive(sampass)))) { need_to_modify = True; - set_single_attribute(obj, NPF_DIR_DRIVE, pdb_get_dirdrive(sampass), - strlen(pdb_get_dirdrive(sampass)), EN_MODIFIED); + set_single_attribute(obj, NPF_DIR_DRIVE, pdb_get_dir_drive(sampass), + strlen(pdb_get_dir_drive(sampass)), EN_MODIFIED); } /* logon_script */ @@ -860,7 +860,7 @@ static BOOL init_nisp_from_sam(nis_object *obj, const SAM_ACCOUNT *sampass, set_single_attribute(obj, NPF_HOME_DIR, homedir, strlen(homedir), 0); - if(!(dirdrive = pdb_get_dirdrive(sampass))) + if(!(dirdrive = pdb_get_dir_drive(sampass))) dirdrive = empty; set_single_attribute(obj, NPF_DIR_DRIVE, @@ -1032,7 +1032,7 @@ BOOL pdb_getsampwnam(SAM_ACCOUNT * user, const char *sname) Routine to search the nisplus passwd file for an entry matching the username *************************************************************************/ -BOOL pdb_getsampwsid(SAM_ACCOUNT * user, DOM_SID *sid) +BOOL pdb_getsampwsid(SAM_ACCOUNT * user, const DOM_SID *sid) { uint32 rid; if (!sid_peek_check_rid(get_global_sam_sid(), sid, &rid)) diff --git a/source3/passdb/pdb_smbpasswd.c b/source3/passdb/pdb_smbpasswd.c index 8c7ba364b8..d40ea03511 100644 --- a/source3/passdb/pdb_smbpasswd.c +++ b/source3/passdb/pdb_smbpasswd.c @@ -1149,7 +1149,7 @@ static BOOL build_smb_pass (struct smb_passwd *smb_pw, const SAM_ACCOUNT *sampas uid = pdb_get_uid(sampass); /* If the user specified a RID, make sure its able to be both stored and retreived */ - if (rid && uid != fallback_pdb_user_rid_to_uid(rid)) { + if (rid && rid != DOMAIN_USER_RID_GUEST && uid != fallback_pdb_user_rid_to_uid(rid)) { DEBUG(0,("build_sam_pass: Failing attempt to store user with non-uid based user RID. \n")); return False; } @@ -1417,7 +1417,7 @@ static BOOL smbpasswd_getsampwrid(struct pdb_methods *my_methods, SAM_ACCOUNT *s return True; } -static BOOL smbpasswd_getsampwsid(struct pdb_methods *my_methods, SAM_ACCOUNT * user, DOM_SID *sid) +static BOOL smbpasswd_getsampwsid(struct pdb_methods *my_methods, SAM_ACCOUNT * user, const DOM_SID *sid) { uint32 rid; if (!sid_peek_check_rid(get_global_sam_sid(), sid, &rid)) diff --git a/source3/passdb/pdb_tdb.c b/source3/passdb/pdb_tdb.c index 6279318969..27453fc1af 100644 --- a/source3/passdb/pdb_tdb.c +++ b/source3/passdb/pdb_tdb.c @@ -354,7 +354,8 @@ static uint32 init_buffer_from_sam (struct tdbsam_privates *tdb_state, * Only updates fields which have been set (not defaults from smb.conf) */ - if (IS_SAM_SET(sampass, FLAG_SAM_DRIVE)) dir_drive = pdb_get_dirdrive(sampass); + if (IS_SAM_SET(sampass, FLAG_SAM_DRIVE)) + dir_drive = pdb_get_dir_drive(sampass); else dir_drive = NULL; if (dir_drive) dir_drive_len = strlen(dir_drive) +1; else dir_drive_len = 0; @@ -541,7 +542,7 @@ static BOOL tdbsam_getsampwent(struct pdb_methods *my_methods, SAM_ACCOUNT *user /* increment to next in line */ tdb_state->key = tdb_nextkey(tdb_state->passwd_tdb, tdb_state->key); - /* do we have an valid interation pointer? */ + /* do we have an valid iteration pointer? */ if(tdb_state->passwd_tdb == NULL) { DEBUG(0,("pdb_get_sampwent: Bad TDB Context pointer.\n")); return False; @@ -668,7 +669,7 @@ static BOOL tdbsam_getsampwrid (struct pdb_methods *my_methods, SAM_ACCOUNT *use return tdbsam_getsampwnam (my_methods, user, name); } -static BOOL tdbsam_getsampwsid(struct pdb_methods *my_methods, SAM_ACCOUNT * user, DOM_SID *sid) +static BOOL tdbsam_getsampwsid(struct pdb_methods *my_methods, SAM_ACCOUNT * user, const DOM_SID *sid) { uint32 rid; if (!sid_peek_check_rid(get_global_sam_sid(), sid, &rid)) diff --git a/source3/passdb/pdb_unix.c b/source3/passdb/pdb_unix.c index b4092b88f8..06f12164eb 100644 --- a/source3/passdb/pdb_unix.c +++ b/source3/passdb/pdb_unix.c @@ -49,23 +49,36 @@ static BOOL unixsam_getsampwrid (struct pdb_methods *methods, { struct passwd *pass; BOOL ret = False; + const char *guest_account = lp_guestaccount(); + if (!(guest_account && *guest_account)) { + DEBUG(1, ("NULL guest account!?!?\n")); + return False; + } + if (!methods) { DEBUG(0,("invalid methods\n")); return False; } - - if (pdb_rid_is_user(rid)) { - pass = getpwuid_alloc(fallback_pdb_user_rid_to_uid (rid)); - - if (pass) { - ret = NT_STATUS_IS_OK(pdb_fill_sam_pw(user, pass)); - passwd_free(&pass); + + if (rid == DOMAIN_USER_RID_GUEST) { + pass = getpwnam_alloc(guest_account); + if (!pass) { + DEBUG(1, ("guest account %s does not seem to exist...\n", guest_account)); + return False; } + } else if (pdb_rid_is_user(rid)) { + pass = getpwuid_alloc(fallback_pdb_user_rid_to_uid (rid)); + } else { + return False; } + + ret = NT_STATUS_IS_OK(pdb_fill_sam_pw(user, pass)); + passwd_free(&pass); + return ret; } -static BOOL unixsam_getsampwsid(struct pdb_methods *my_methods, SAM_ACCOUNT * user, DOM_SID *sid) +static BOOL unixsam_getsampwsid(struct pdb_methods *my_methods, SAM_ACCOUNT * user, const DOM_SID *sid) { uint32 rid; if (!sid_peek_check_rid(get_global_sam_sid(), sid, &rid)) diff --git a/source3/passdb/secrets.c b/source3/passdb/secrets.c index 3ecaf52e58..ec67b74390 100644 --- a/source3/passdb/secrets.c +++ b/source3/passdb/secrets.c @@ -128,6 +128,47 @@ BOOL secrets_fetch_domain_sid(char *domain, DOM_SID *sid) return True; } +BOOL secrets_store_domain_guid(char *domain, GUID *guid) +{ + fstring key; + + slprintf(key, sizeof(key)-1, "%s/%s", SECRETS_DOMAIN_GUID, domain); + strupper(key); + return secrets_store(key, guid, sizeof(GUID)); +} + +BOOL secrets_fetch_domain_guid(char *domain, GUID *guid) +{ + GUID *dyn_guid; + fstring key; + size_t size; + GUID new_guid; + + slprintf(key, sizeof(key)-1, "%s/%s", SECRETS_DOMAIN_GUID, domain); + strupper(key); + dyn_guid = (GUID *)secrets_fetch(key, &size); + + DEBUG(6,("key is %s, guid is at %x, size is %d\n", key, dyn_guid, size)); + + if ((NULL == dyn_guid) && (ROLE_DOMAIN_PDC == lp_server_role())) { + uuid_generate_random(&new_guid); + if (!secrets_store_domain_guid(domain, &new_guid)) + return False; + dyn_guid = (GUID *)secrets_fetch(key, &size); + if (dyn_guid == NULL) + return False; + } + + if (size != sizeof(GUID)) + { + SAFE_FREE(dyn_guid); + return False; + } + + *guid = *dyn_guid; + SAFE_FREE(dyn_guid); + return True; +} /** * Form a key for fetching the machine trust account password @@ -178,7 +219,7 @@ BOOL secrets_fetch_trust_account_password(char *domain, uint8 ret_pwd[16], if (plaintext) { /* we have an ADS password - use that */ DEBUG(4,("Using ADS machine password\n")); - E_md4hash((uchar *)plaintext, ret_pwd); + E_md4hash(plaintext, ret_pwd); SAFE_FREE(plaintext); return True; } @@ -388,7 +429,9 @@ BOOL secrets_store_ldap_pw(const char* dn, char* pw) /** - * The linked list is allocated on the supplied talloc context, caller gets to destory + * Get trusted domains info from secrets.tdb. + * + * The linked list is allocated on the supplied talloc context, caller gets to destroy * when done. * * @param ctx Allocation context @@ -409,10 +452,11 @@ NTSTATUS secrets_get_trusted_domains(TALLOC_CTX* ctx, int* enum_ctx, int max_num int start_idx; uint32 idx = 0; size_t size; + fstring dom_name; struct trusted_dom_pass *pass; NTSTATUS status; - secrets_init(); + if (!secrets_init()) return NT_STATUS_ACCESS_DENIED; *num_domains = 0; start_idx = *enum_ctx; @@ -455,6 +499,10 @@ NTSTATUS secrets_get_trusted_domains(TALLOC_CTX* ctx, int* enum_ctx, int max_num SAFE_FREE(pass); continue; } + + pull_ucs2_fstring(dom_name, pass->uni_name); + DEBUG(18, ("Fetched secret record num %d.\nDomain name: %s, SID: %s\n", + idx, dom_name, sid_string_static(&pass->domain_sid))); SAFE_FREE(secrets_key); @@ -475,6 +523,10 @@ NTSTATUS secrets_get_trusted_domains(TALLOC_CTX* ctx, int* enum_ctx, int max_num dom->name = talloc_strdup_w(ctx, pass->uni_name); (*domains)[idx - start_idx] = dom; + + DEBUG(18, ("Secret record is in required range.\n \ + start_idx = %d, max_num_domains = %d. Added to returned array.\n", + start_idx, max_num_domains)); *enum_ctx = idx + 1; (*num_domains)++; @@ -487,6 +539,10 @@ NTSTATUS secrets_get_trusted_domains(TALLOC_CTX* ctx, int* enum_ctx, int max_num /* this is the last entry in the whole enumeration */ status = NT_STATUS_OK; } + } else { + DEBUG(18, ("Secret is outside the required range.\n \ + start_idx = %d, max_num_domains = %d. Not added to returned array\n", + start_idx, max_num_domains)); } idx++; diff --git a/source3/passdb/util_sam_sid.c b/source3/passdb/util_sam_sid.c index 2c574f4a61..6ec1e48ab3 100644 --- a/source3/passdb/util_sam_sid.c +++ b/source3/passdb/util_sam_sid.c @@ -95,6 +95,9 @@ static void init_sid_name_map (void) if ((lp_security() == SEC_USER) && lp_domain_logons()) { sid_name_map[i].sid = get_global_sam_sid(); + /* This is not lp_workgroup() for good reason: + it must stay around longer than the lp_*() + strings do */ sid_name_map[i].name = global_myworkgroup; sid_name_map[i].known_users = NULL; i++; -- cgit