summaryrefslogtreecommitdiff
path: root/source3/passdb
diff options
context:
space:
mode:
authorJelmer Vernooij <jelmer@samba.org>2002-08-17 17:00:51 +0000
committerJelmer Vernooij <jelmer@samba.org>2002-08-17 17:00:51 +0000
commitb2edf254eda92f775e7d3d9b6793b4d77f9000b6 (patch)
tree18eb2564a769678c774a19bb07c00fc4aa7b2758 /source3/passdb
parent669a39fae36f8bc60753c9b352556ef8ffaeb568 (diff)
downloadsamba-b2edf254eda92f775e7d3d9b6793b4d77f9000b6.tar.gz
samba-b2edf254eda92f775e7d3d9b6793b4d77f9000b6.tar.bz2
samba-b2edf254eda92f775e7d3d9b6793b4d77f9000b6.zip
sync 3.0 branch with head
(This used to be commit 3928578b52cfc949be5e0ef444fce1558d75f290)
Diffstat (limited to 'source3/passdb')
-rw-r--r--source3/passdb/passdb.c158
-rw-r--r--source3/passdb/pdb_get_set.c11
-rw-r--r--source3/passdb/pdb_interface.c6
-rw-r--r--source3/passdb/pdb_ldap.c179
-rw-r--r--source3/passdb/pdb_nisplus.c16
-rw-r--r--source3/passdb/pdb_smbpasswd.c4
-rw-r--r--source3/passdb/pdb_tdb.c7
-rw-r--r--source3/passdb/pdb_unix.c29
-rw-r--r--source3/passdb/secrets.c62
-rw-r--r--source3/passdb/util_sam_sid.c3
10 files changed, 336 insertions, 139 deletions
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,43 +270,92 @@ 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.
******************************************************************/
static BOOL ldapsam_connect_system(struct ldapsam_privates *ldap_state, LDAP * ldap_struct)
@@ -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++;