[SCM] Samba Shared Repository - branch master updated
Andrew Bartlett
abartlet at samba.org
Mon Jun 7 06:51:01 MDT 2010
The branch, master has been updated
via 00089fd... s3:auth make sure the primary group sid is usable
via 048575d... s3:auth return the full passwd struct from check_account
via 0a7ff14... s3:passdb Export function to calculate the proper primary group sid
via aaf45cd... s3:auth remove unused structure member
via aa1a3cb... s3:auth create nt token from info3 directly
via e6456df... s3:auth handle unix domain sids in samu
via 61823fb... s3:auth set the resolved user sid in the fake sam account
via ef94217... s3:auth check the user is valid first
via 1bb0afa... s3:auth make sure we set the right username
from aa32725... s4:ldap.py - add some "objectclass" behaviour tests
http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master
- Log -----------------------------------------------------------------
commit 00089fd74af740f832573d904312854e494a869e
Author: Simo Sorce <ssorce at redhat.com>
Date: Sat May 29 11:29:29 2010 -0400
s3:auth make sure the primary group sid is usable
This function was previously performed under the cover by converting
back and forth from info3 to samu and then later from samu to info3.
Since we now shortcircuit that in some cases, check explicitly using
get_primary_group_sid()
Signed-off-by: Andrew Bartlett <abartlet at samba.org>
commit 048575defba064a8d9f0e4eb542a299dc8730327
Author: Simo Sorce <ssorce at redhat.com>
Date: Sat May 29 11:02:47 2010 -0400
s3:auth return the full passwd struct from check_account
Signed-off-by: Andrew Bartlett <abartlet at samba.org>
commit 0a7ff146171abd2dee4aac44e4f2c6c812f1027e
Author: Simo Sorce <ssorce at redhat.com>
Date: Sat May 29 10:51:40 2010 -0400
s3:passdb Export function to calculate the proper primary group sid
Don't keep it buried in passdb, this function need to be available
for use in places where we do not want to construct an artificial
samu struct just to play tricks.
Signed-off-by: Andrew Bartlett <abartlet at samba.org>
commit aaf45cd48ecf8e9f640a6f487b66785d47b8154a
Author: Simo Sorce <ssorce at redhat.com>
Date: Fri May 28 17:03:18 2010 -0400
s3:auth remove unused structure member
sids are now completely handled using info3, remove dead code that fills
server info sids and the structure members themselves
Signed-off-by: Andrew Bartlett <abartlet at samba.org>
commit aa1a3cbad2ed62d5b59c48a6e7726eef4776f461
Author: Simo Sorce <ssorce at redhat.com>
Date: Fri May 28 16:16:53 2010 -0400
s3:auth create nt token from info3 directly
Signed-off-by: Andrew Bartlett <abartlet at samba.org>
commit e6456df1489ec964445dfd6f009f9f75377b3d11
Author: Simo Sorce <ssorce at redhat.com>
Date: Fri May 28 13:18:13 2010 -0400
s3:auth handle unix domain sids in samu
When we generate a user out of thin air we may end up adding sids
that are not part of the sam domain (unix domain sids).
Handle the case and preserve these sids as extra sids.
Signed-off-by: Andrew Bartlett <abartlet at samba.org>
commit 61823fb8852cb8d66c341ecd54e7fb96abc4363a
Author: Simo Sorce <ssorce at redhat.com>
Date: Fri May 28 13:22:41 2010 -0400
s3:auth set the resolved user sid in the fake sam account
Signed-off-by: Andrew Bartlett <abartlet at samba.org>
commit ef942172b9dfe3c30b86161445c7d6290579b6f2
Author: Simo Sorce <ssorce at redhat.com>
Date: Fri May 28 11:14:01 2010 -0400
s3:auth check the user is valid first
It makes no sense to go through all the hoops to build samu and
convert it to info3, just to discard them later if the user was
not valid.
Signed-off-by: Andrew Bartlett <abartlet at samba.org>
commit 1bb0afa662cb65ad8eeec59d40008c6604b791bc
Author: Simo Sorce <ssorce at redhat.com>
Date: Fri May 28 11:07:49 2010 -0400
s3:auth make sure we set the right username
Signed-off-by: Andrew Bartlett <abartlet at samba.org>
-----------------------------------------------------------------------
Summary of changes:
source3/auth/auth_util.c | 219 ++++++++++++++--------------------------
source3/auth/server_info.c | 158 +++++++++++++++++++++++------
source3/auth/server_info_sam.c | 36 +------
source3/auth/token_util.c | 183 ++++++++++++++++++++++++++++-----
source3/include/auth.h | 16 ++-
source3/include/proto.h | 12 ++-
source3/passdb/lookup_sid.c | 124 +++++++++++++++++++++++
source3/passdb/pdb_get_set.c | 94 ++----------------
8 files changed, 516 insertions(+), 326 deletions(-)
Changeset truncated at 500 lines:
diff --git a/source3/auth/auth_util.c b/source3/auth/auth_util.c
index a64fd33..a93d44f 100644
--- a/source3/auth/auth_util.c
+++ b/source3/auth/auth_util.c
@@ -30,34 +30,6 @@
#define DBGC_CLASS DBGC_AUTH
/****************************************************************************
- Ensure primary group SID is always at position 0 in a
- auth_serversupplied_info struct.
-****************************************************************************/
-
-static void sort_sid_array_for_smbd(struct auth_serversupplied_info *result,
- const struct dom_sid *pgroup_sid)
-{
- unsigned int i;
-
- if (!result->sids) {
- return;
- }
-
- if (sid_compare(&result->sids[0], pgroup_sid)==0) {
- return;
- }
-
- for (i = 1; i < result->num_sids; i++) {
- if (sid_compare(pgroup_sid,
- &result->sids[i]) == 0) {
- sid_copy(&result->sids[i], &result->sids[0]);
- sid_copy(&result->sids[0], pgroup_sid);
- return;
- }
- }
-}
-
-/****************************************************************************
Create a UNIX user on demand.
****************************************************************************/
@@ -463,7 +435,6 @@ NTSTATUS create_local_token(struct auth_serversupplied_info *server_info)
NTSTATUS status;
size_t i;
struct dom_sid tmp_sid;
- struct dom_sid user_sid;
/*
* If winbind is not around, we can not make much use of the SIDs the
@@ -482,17 +453,11 @@ NTSTATUS create_local_token(struct auth_serversupplied_info *server_info)
&server_info->ptok);
} else {
- sid_compose(&user_sid,
- server_info->info3->base.domain_sid,
- server_info->info3->base.rid);
-
- server_info->ptok = create_local_nt_token(
- server_info,
- &user_sid,
- server_info->guest,
- server_info->num_sids, server_info->sids);
- status = server_info->ptok ?
- NT_STATUS_OK : NT_STATUS_NO_SUCH_USER;
+ status = create_local_nt_token_from_info3(server_info,
+ server_info->guest,
+ server_info->info3,
+ &server_info->extra,
+ &server_info->ptok);
}
if (!NT_STATUS_IS_OK(status)) {
@@ -574,66 +539,12 @@ NTSTATUS make_server_info_pw(struct auth_serversupplied_info **server_info,
{
NTSTATUS status;
struct samu *sampass = NULL;
- gid_t *gids;
char *qualified_name = NULL;
TALLOC_CTX *mem_ctx = NULL;
struct dom_sid u_sid;
enum lsa_SidType type;
struct auth_serversupplied_info *result;
- if ( !(sampass = samu_new( NULL )) ) {
- return NT_STATUS_NO_MEMORY;
- }
-
- status = samu_set_unix( sampass, pwd );
- if (!NT_STATUS_IS_OK(status)) {
- return status;
- }
-
- result = make_server_info(NULL);
- if (result == NULL) {
- TALLOC_FREE(sampass);
- return NT_STATUS_NO_MEMORY;
- }
-
- status = samu_to_SamInfo3(result, sampass,
- global_myname(), &result->info3);
- if (!NT_STATUS_IS_OK(status)) {
- DEBUG(10, ("Failed to convert samu to info3: %s\n",
- nt_errstr(status)));
- TALLOC_FREE(sampass);
- TALLOC_FREE(result);
- return status;
- }
-
-
- result->unix_name = talloc_strdup(result, unix_username);
- result->sanitized_username = sanitize_username(result, unix_username);
-
- if ((result->unix_name == NULL)
- || (result->sanitized_username == NULL)) {
- TALLOC_FREE(sampass);
- TALLOC_FREE(result);
- return NT_STATUS_NO_MEMORY;
- }
-
- result->utok.uid = pwd->pw_uid;
- result->utok.gid = pwd->pw_gid;
-
- status = pdb_enum_group_memberships(result, sampass,
- &result->sids, &gids,
- &result->num_sids);
-
- if (!NT_STATUS_IS_OK(status)) {
- DEBUG(10, ("pdb_enum_group_memberships failed: %s\n",
- nt_errstr(status)));
- TALLOC_FREE(sampass);
- TALLOC_FREE(result);
- return status;
- }
-
- TALLOC_FREE(sampass);
-
/*
* The SID returned in server_info->sam_account is based
* on our SAM sid even though for a pure UNIX account this should
@@ -649,7 +560,6 @@ NTSTATUS make_server_info_pw(struct auth_serversupplied_info **server_info,
mem_ctx = talloc_init("make_server_info_pw_tmp");
if (!mem_ctx) {
- TALLOC_FREE(result);
return NT_STATUS_NO_MEMORY;
}
@@ -657,7 +567,6 @@ NTSTATUS make_server_info_pw(struct auth_serversupplied_info **server_info,
unix_users_domain_name(),
unix_username );
if (!qualified_name) {
- TALLOC_FREE(result);
TALLOC_FREE(mem_ctx);
return NT_STATUS_NO_MEMORY;
}
@@ -665,7 +574,6 @@ NTSTATUS make_server_info_pw(struct auth_serversupplied_info **server_info,
if (!lookup_name(mem_ctx, qualified_name, LOOKUP_NAME_ALL,
NULL, NULL,
&u_sid, &type)) {
- TALLOC_FREE(result);
TALLOC_FREE(mem_ctx);
return NT_STATUS_NO_SUCH_USER;
}
@@ -673,23 +581,55 @@ NTSTATUS make_server_info_pw(struct auth_serversupplied_info **server_info,
TALLOC_FREE(mem_ctx);
if (type != SID_NAME_USER) {
- TALLOC_FREE(result);
return NT_STATUS_NO_SUCH_USER;
}
- /* FIXME: add to info3 too ? */
- status = add_sid_to_array_unique(result, &u_sid,
- &result->sids,
- &result->num_sids);
+ if ( !(sampass = samu_new( NULL )) ) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ status = samu_set_unix( sampass, pwd );
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
+ /* In pathological cases the above call can set the account
+ * name to the DOMAIN\username form. Reset the account name
+ * using unix_username */
+ pdb_set_username(sampass, unix_username, PDB_SET);
+
+ /* set the user sid to be the calculated u_sid */
+ pdb_set_user_sid(sampass, &u_sid, PDB_SET);
+
+ result = make_server_info(NULL);
+ if (result == NULL) {
+ TALLOC_FREE(sampass);
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ status = samu_to_SamInfo3(result, sampass, global_myname(),
+ &result->info3, &result->extra);
if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(10, ("Failed to convert samu to info3: %s\n",
+ nt_errstr(status)));
+ TALLOC_FREE(sampass);
TALLOC_FREE(result);
return status;
}
- /* For now we throw away the gids and convert via sid_to_gid
- * later. This needs fixing, but I'd like to get the code straight and
- * simple first. */
- TALLOC_FREE(gids);
+ TALLOC_FREE(sampass);
+
+ result->unix_name = talloc_strdup(result, unix_username);
+ result->sanitized_username = sanitize_username(result, unix_username);
+
+ if ((result->unix_name == NULL)
+ || (result->sanitized_username == NULL)) {
+ TALLOC_FREE(result);
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ result->utok.uid = pwd->pw_uid;
+ result->utok.gid = pwd->pw_gid;
*server_info = result;
@@ -867,6 +807,7 @@ struct auth_serversupplied_info *copy_serverinfo(TALLOC_CTX *mem_ctx,
TALLOC_FREE(dst);
return NULL;
}
+ dst->extra = src->extra;
dst->pam_handle = NULL;
dst->unix_name = talloc_strdup(dst, src->unix_name);
@@ -968,7 +909,7 @@ bool copy_current_user(struct current_user *dst, struct current_user *src)
static NTSTATUS check_account(TALLOC_CTX *mem_ctx, const char *domain,
const char *username, char **found_username,
- uid_t *uid, gid_t *gid,
+ struct passwd **pwd,
bool *username_was_mapped)
{
fstring dom_user, lower_username;
@@ -992,8 +933,7 @@ static NTSTATUS check_account(TALLOC_CTX *mem_ctx, const char *domain,
return NT_STATUS_NO_SUCH_USER;
}
- *uid = passwd->pw_uid;
- *gid = passwd->pw_gid;
+ *pwd = passwd;
/* This is pointless -- there is no suport for differing
unix and windows names. Make sure to always store the
@@ -1003,8 +943,6 @@ static NTSTATUS check_account(TALLOC_CTX *mem_ctx, const char *domain,
*found_username = talloc_strdup( mem_ctx, real_username );
- TALLOC_FREE(passwd);
-
return NT_STATUS_OK;
}
@@ -1109,14 +1047,11 @@ NTSTATUS make_server_info_info3(TALLOC_CTX *mem_ctx,
char *found_username = NULL;
const char *nt_domain;
const char *nt_username;
- struct dom_sid user_sid;
- struct dom_sid group_sid;
bool username_was_mapped;
-
- uid_t uid = (uid_t)-1;
- gid_t gid = (gid_t)-1;
-
+ struct passwd *pwd;
struct auth_serversupplied_info *result;
+ struct dom_sid *group_sid;
+ struct netr_SamInfo3 *i3;
/*
Here is where we should check the list of
@@ -1124,15 +1059,6 @@ NTSTATUS make_server_info_info3(TALLOC_CTX *mem_ctx,
matches.
*/
- if (!sid_compose(&user_sid, info3->base.domain_sid, info3->base.rid)) {
- return NT_STATUS_INVALID_PARAMETER;
- }
-
- if (!sid_compose(&group_sid, info3->base.domain_sid,
- info3->base.primary_gid)) {
- return NT_STATUS_INVALID_PARAMETER;
- }
-
nt_username = talloc_strdup(mem_ctx, info3->base.account_name.string);
if (!nt_username) {
/* If the server didn't give us one, just use the one we sent
@@ -1161,7 +1087,7 @@ NTSTATUS make_server_info_info3(TALLOC_CTX *mem_ctx,
/* this call will try to create the user if necessary */
nt_status = check_account(mem_ctx, nt_domain, sent_nt_username,
- &found_username, &uid, &gid,
+ &found_username, &pwd,
&username_was_mapped);
if (!NT_STATUS_IS_OK(nt_status)) {
@@ -1184,29 +1110,38 @@ NTSTATUS make_server_info_info3(TALLOC_CTX *mem_ctx,
}
/* copy in the info3 */
- result->info3 = copy_netr_SamInfo3(result, info3);
+ result->info3 = i3 = copy_netr_SamInfo3(result, info3);
/* Fill in the unix info we found on the way */
+ result->utok.uid = pwd->pw_uid;
+ result->utok.gid = pwd->pw_gid;
- result->utok.uid = uid;
- result->utok.gid = gid;
-
- /* Create a 'combined' list of all SIDs we might want in the SD */
-
- result->num_sids = 0;
- result->sids = NULL;
-
- nt_status = sid_array_from_info3(result, info3,
- &result->sids,
- &result->num_sids,
- false, false);
+ /* We can't just trust that the primary group sid sent us is something
+ * we can really use. Obtain the useable sid, and store the original
+ * one as an additional group if it had to be replaced */
+ nt_status = get_primary_group_sid(mem_ctx, found_username,
+ &pwd, &group_sid);
if (!NT_STATUS_IS_OK(nt_status)) {
TALLOC_FREE(result);
return nt_status;
}
- /* Ensure the primary group sid is at position 0. */
- sort_sid_array_for_smbd(result, &group_sid);
+ /* store and check if it is the same we got originally */
+ sid_peek_rid(group_sid, &i3->base.primary_gid);
+ if (i3->base.primary_gid != info3->base.primary_gid) {
+ uint32_t n = i3->base.groups.count;
+ /* not the same, store the original as an additional group */
+ i3->base.groups.rids =
+ talloc_realloc(i3, i3->base.groups.rids,
+ struct samr_RidWithAttribute, n + 1);
+ if (i3->base.groups.rids == NULL) {
+ TALLOC_FREE(result);
+ return NT_STATUS_NO_MEMORY;
+ }
+ i3->base.groups.rids[n].rid = info3->base.primary_gid;
+ i3->base.groups.rids[n].attributes = SE_GROUP_ENABLED;
+ i3->base.groups.count = n + 1;
+ }
/* ensure we are never given NULL session keys */
diff --git a/source3/auth/server_info.c b/source3/auth/server_info.c
index f72cdba..6b43fc6 100644
--- a/source3/auth/server_info.c
+++ b/source3/auth/server_info.c
@@ -53,6 +53,7 @@ struct auth_serversupplied_info *make_server_info(TALLOC_CTX *mem_ctx)
result->utok.uid = -1;
result->utok.gid = -1;
+
return result;
}
@@ -215,37 +216,81 @@ NTSTATUS serverinfo_to_SamInfo6(struct auth_serversupplied_info *server_info,
return NT_STATUS_OK;
}
-static NTSTATUS sids_to_samr_RidWithAttributeArray(
- TALLOC_CTX *mem_ctx,
- struct samr_RidWithAttributeArray *groups,
- const struct dom_sid *domain_sid,
- const struct dom_sid *sids,
- size_t num_sids)
+static NTSTATUS append_netr_SidAttr(TALLOC_CTX *mem_ctx,
+ struct netr_SidAttr **sids,
+ uint32_t *count,
+ const struct dom_sid2 *asid,
+ uint32_t attributes)
+{
+ uint32_t t = *count;
+
+ *sids = talloc_realloc(mem_ctx, *sids, struct netr_SidAttr, t + 1);
+ if (*sids == NULL) {
+ return NT_STATUS_NO_MEMORY;
+ }
+ (*sids)[t].sid = sid_dup_talloc(*sids, asid);
+ if ((*sids)[t].sid == NULL) {
+ return NT_STATUS_NO_MEMORY;
+ }
+ (*sids)[t].attributes = attributes;
+ *count = t + 1;
+
+ return NT_STATUS_OK;
+}
+
+/* Fils the samr_RidWithAttributeArray with the provided sids.
+ * If it happens that we have additional groups that do not belong
+ * to the domain, add their sids as extra sids */
+static NTSTATUS group_sids_to_info3(struct netr_SamInfo3 *info3,
+ const struct dom_sid *sids,
+ size_t num_sids)
{
+ uint32_t attributes = SE_GROUP_MANDATORY |
+ SE_GROUP_ENABLED_BY_DEFAULT |
+ SE_GROUP_ENABLED;
+ struct samr_RidWithAttributeArray *groups;
+ struct dom_sid *domain_sid;
unsigned int i;
+ NTSTATUS status;
+ uint32_t rid;
bool ok;
- groups->rids = talloc_array(mem_ctx,
+ domain_sid = info3->base.domain_sid;
+ groups = &info3->base.groups;
+
+ groups->rids = talloc_array(info3,
struct samr_RidWithAttribute, num_sids);
if (!groups->rids) {
return NT_STATUS_NO_MEMORY;
}
for (i = 0; i < num_sids; i++) {
- ok = sid_peek_check_rid(domain_sid, &sids[i],
- &groups->rids[i].rid);
- if (!ok) continue;
+ ok = sid_peek_check_rid(domain_sid, &sids[i], &rid);
+ if (ok) {
+
+ /* if it is the primary gid, skip it, we
+ * obviously already have it */
+ if (info3->base.primary_gid == rid) continue;
+
+ /* store domain group rid */
+ groups->rids[i].rid = rid;
+ groups->rids[i].attributes = attributes;
+ groups->count++;
+ continue;
+ }
- groups->rids[i].attributes = SE_GROUP_MANDATORY |
- SE_GROUP_ENABLED_BY_DEFAULT |
- SE_GROUP_ENABLED;
- groups->count++;
+ /* if this wasn't a domain sid, add it as extra sid */
+ status = append_netr_SidAttr(info3, &info3->sids,
+ &info3->sidcount,
+ &sids[i], attributes);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
}
return NT_STATUS_OK;
}
-
#define RET_NOMEM(ptr) do { \
if (!ptr) { \
TALLOC_FREE(info3); \
@@ -255,7 +300,8 @@ static NTSTATUS sids_to_samr_RidWithAttributeArray(
NTSTATUS samu_to_SamInfo3(TALLOC_CTX *mem_ctx,
struct samu *samu,
const char *login_server,
- struct netr_SamInfo3 **_info3)
+ struct netr_SamInfo3 **_info3,
+ struct extra_auth_info *extra)
{
struct netr_SamInfo3 *info3;
const struct dom_sid *user_sid;
@@ -281,6 +327,67 @@ NTSTATUS samu_to_SamInfo3(TALLOC_CTX *mem_ctx,
return NT_STATUS_NO_MEMORY;
}
+ ZERO_STRUCT(domain_sid);
+
+ /* check if this is a "Unix Users" domain user,
+ * we need to handle it in a special way if that's the case */
+ if (sid_compare_domain(user_sid, &global_sid_Unix_Users) == 0) {
+ /* in info3 you can only set rids for the user and the
+ * primary group, and the domain sid must be that of
+ * the sam domain.
+ *
+ * Store a completely bogus value here.
+ * The real SID is stored in the extra sids.
+ * Other code will know to look there if (-1) is found
+ */
+ info3->base.rid = (uint32_t)(-1);
+ sid_copy(&extra->user_sid, user_sid);
+
+ DEBUG(10, ("Unix User found in struct samu. Rid marked as "
+ "special and sid (%s) saved as extra sid\n",
--
Samba Shared Repository
More information about the samba-cvs
mailing list