diff --git a/source3/auth/auth_util.c b/source3/auth/auth_util.c index dbc7d24..585afd3 100644 --- a/source3/auth/auth_util.c +++ b/source3/auth/auth_util.c @@ -671,7 +671,8 @@ NTSTATUS make_server_info_pw(TALLOC_CTX *mem_ctx, status = passwd_to_SamInfo3(result, unix_username, pwd, - &result->info3); + &result->info3, + &result->extra); if (!NT_STATUS_IS_OK(status)) { goto done; } diff --git a/source3/auth/proto.h b/source3/auth/proto.h index da3c099..792e96d 100644 --- a/source3/auth/proto.h +++ b/source3/auth/proto.h @@ -305,7 +305,8 @@ NTSTATUS samu_to_SamInfo3(TALLOC_CTX *mem_ctx, NTSTATUS passwd_to_SamInfo3(TALLOC_CTX *mem_ctx, const char *unix_username, const struct passwd *pwd, - struct netr_SamInfo3 **pinfo3); + struct netr_SamInfo3 **pinfo3, + struct extra_auth_info *extra); struct netr_SamInfo3 *copy_netr_SamInfo3(TALLOC_CTX *mem_ctx, const struct netr_SamInfo3 *orig); diff --git a/source3/auth/server_info.c b/source3/auth/server_info.c index 8fd3b0d..86b3dd3 100644 --- a/source3/auth/server_info.c +++ b/source3/auth/server_info.c @@ -517,7 +517,8 @@ NTSTATUS samu_to_SamInfo3(TALLOC_CTX *mem_ctx, NTSTATUS passwd_to_SamInfo3(TALLOC_CTX *mem_ctx, const char *unix_username, const struct passwd *pwd, - struct netr_SamInfo3 **pinfo3) + struct netr_SamInfo3 **pinfo3, + struct extra_auth_info *extra) { struct netr_SamInfo3 *info3; NTSTATUS status; @@ -613,23 +614,68 @@ NTSTATUS passwd_to_SamInfo3(TALLOC_CTX *mem_ctx, ZERO_STRUCT(domain_sid); - sid_copy(&domain_sid, &user_sid); - sid_split_rid(&domain_sid, &info3->base.rid); + /* 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_check_is_in_unix_users(&user_sid)) { + /* 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 passwd. Rid marked as " + "special and sid (%s) saved as extra sid\n", + sid_string_dbg(&user_sid))); + } else { + sid_copy(&domain_sid, &user_sid); + sid_split_rid(&domain_sid, &info3->base.rid); + } + + if (is_null_sid(&domain_sid)) { + sid_copy(&domain_sid, get_global_sam_sid()); + } + info3->base.domain_sid = dom_sid_dup(info3, &domain_sid); - ok = sid_peek_check_rid(&domain_sid, &group_sid, + /* check if this is a "Unix Groups" domain group, + * if so we need special handling */ + if (sid_check_is_in_unix_groups(&group_sid)) { + /* 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.primary_gid = (uint32_t)(-1); + sid_copy(&extra->pgid_sid, &group_sid); + + DEBUG(10, ("Unix Group found in passwd. Rid marked as " + "special and sid (%s) saved as extra sid\n", + sid_string_dbg(&group_sid))); + + } else { + ok = sid_peek_check_rid(&domain_sid, &group_sid, &info3->base.primary_gid); - if (!ok) { - DEBUG(1, ("The primary group domain sid(%s) does not " - "match the domain sid(%s) for %s(%s)\n", - sid_string_dbg(&group_sid), - sid_string_dbg(&domain_sid), - unix_username, - sid_string_dbg(&user_sid))); - status = NT_STATUS_INVALID_SID; - goto done; + if (!ok) { + DEBUG(1, ("The primary group domain sid(%s) does not " + "match the domain sid(%s) for %s(%s)\n", + sid_string_dbg(&group_sid), + sid_string_dbg(&domain_sid), + unix_username, + sid_string_dbg(&user_sid))); + status = NT_STATUS_INVALID_SID; + goto done; + } } + info3->base.user_flags = NETLOGON_EXTRA_SIDS; info3->base.acct_flags = ACB_NORMAL; if (num_sids) {