#include "system/passwd.h"
#include "auth.h"
#include "secrets.h"
-#include "memcache.h"
+#include "../lib/util/memcache.h"
#include "../librpc/gen_ndr/netlogon.h"
#include "../libcli/security/security.h"
#include "../lib/util/util_pw.h"
return result;
}
+/***************************************************
+ Merge in any groups from /etc/group.
+***************************************************/
+
+static NTSTATUS add_local_groups(struct security_token *result,
+ bool is_guest)
+{
+ gid_t *gids = NULL;
+ uint32_t getgroups_num_group_sids = 0;
+ struct passwd *pass = NULL;
+ TALLOC_CTX *tmp_ctx = talloc_stackframe();
+ int i;
+
+ if (is_guest) {
+ /*
+ * Guest is a special case. It's always
+ * a user that can be looked up, but
+ * result->sids[0] is set to DOMAIN\Guest.
+ * Lookup by account name instead.
+ */
+ pass = Get_Pwnam_alloc(tmp_ctx, lp_guest_account());
+ } else {
+ uid_t uid;
+
+ /* For non-guest result->sids[0] is always the user sid. */
+ if (!sid_to_uid(&result->sids[0], &uid)) {
+ /*
+ * Non-mappable SID like SYSTEM.
+ * Can't be in any /etc/group groups.
+ */
+ TALLOC_FREE(tmp_ctx);
+ return NT_STATUS_OK;
+ }
+
+ pass = getpwuid_alloc(tmp_ctx, uid);
+ if (pass == NULL) {
+ DEBUG(1, ("SID %s -> getpwuid(%u) failed\n",
+ sid_string_dbg(&result->sids[0]),
+ (unsigned int)uid));
+ }
+ }
+
+ if (!pass) {
+ TALLOC_FREE(tmp_ctx);
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+
+ /*
+ * Now we must get any groups this user has been
+ * added to in /etc/group and merge them in.
+ * This has to be done in every code path
+ * that creates an NT token, as remote users
+ * may have been added to the local /etc/group
+ * database. Tokens created merely from the
+ * info3 structs (via the DC or via the krb5 PAC)
+ * won't have these local groups. Note the
+ * groups added here will only be UNIX groups
+ * (S-1-22-2-XXXX groups) as getgroups_unix_user()
+ * turns off winbindd before calling getgroups().
+ *
+ * NB. This is duplicating work already
+ * done in the 'unix_user:' case of
+ * create_token_from_sid() but won't
+ * do anything other than be inefficient
+ * in that case.
+ */
+
+ if (!getgroups_unix_user(tmp_ctx, pass->pw_name, pass->pw_gid,
+ &gids, &getgroups_num_group_sids)) {
+ DEBUG(1, ("getgroups_unix_user for user %s failed\n",
+ pass->pw_name));
+ TALLOC_FREE(tmp_ctx);
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+
+ for (i=0; i<getgroups_num_group_sids; i++) {
+ NTSTATUS status;
+ struct dom_sid grp_sid;
+ gid_to_sid(&grp_sid, gids[i]);
+
+ status = add_sid_to_array_unique(result,
+ &grp_sid,
+ &result->sids,
+ &result->num_sids);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(3, ("Failed to add UNIX SID to nt token\n"));
+ TALLOC_FREE(tmp_ctx);
+ return status;
+ }
+ }
+ TALLOC_FREE(tmp_ctx);
+ return NT_STATUS_OK;
+}
+
static NTSTATUS finalize_local_nt_token(struct security_token *result,
bool is_guest)
{
struct dom_sid dom_sid;
- gid_t gid;
NTSTATUS status;
+ struct acct_info *info;
+
+ /* Add any local groups. */
+
+ status = add_local_groups(result, is_guest);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
/* Add in BUILTIN sids */
}
}
+ info = talloc_zero(talloc_tos(), struct acct_info);
+ if (info == NULL) {
+ DEBUG(0, ("talloc failed!\n"));
+ return NT_STATUS_NO_MEMORY;
+ }
+
/* Deal with the BUILTIN\Administrators group. If the SID can
be resolved then assume that the add_aliasmem( S-1-5-32 )
handled it. */
- if (!sid_to_gid(&global_sid_Builtin_Administrators, &gid)) {
+ status = pdb_get_aliasinfo(&global_sid_Builtin_Administrators, info);
+ if (!NT_STATUS_IS_OK(status)) {
become_root();
if (!secrets_fetch_domain_sid(lp_workgroup(), &dom_sid)) {
be resolved then assume that the add_aliasmem( S-1-5-32 )
handled it. */
- if (!sid_to_gid(&global_sid_Builtin_Users, &gid)) {
+ status = pdb_get_aliasinfo(&global_sid_Builtin_Users, info);
+ if (!NT_STATUS_IS_OK(status)) {
become_root();
if (!secrets_fetch_domain_sid(lp_workgroup(), &dom_sid)) {
}
}
+ TALLOC_FREE(info);
+
/* Deal with local groups */
if (lp_winbind_nested_groups()) {
gid_t *gids;
struct dom_sid *group_sids;
struct dom_sid unix_group_sid;
+ struct dom_sid tmp_sid;
uint32_t num_group_sids;
uint32_t num_gids;
uint32_t i;
/*
* If the SID from lookup_name() was the guest sid, passdb knows
- * about the mapping of guest sid to lp_guestaccount()
+ * about the mapping of guest sid to lp_guest_account()
* username and will return the unix_pw info for a guest
* user. Use it if it's there, else lookup the *uid details
* using Get_Pwnam_alloc(). See bug #6291 for details. JRA.
*uid = sam_acct->unix_pw->pw_uid;
} else if (sid_check_is_in_unix_users(user_sid)) {
- struct dom_sid tmp_sid;
uint32_t getgroups_num_group_sids;
/* This is a unix user not in passdb. We need to ask nss
* directly, without consulting passdb */