summaryrefslogtreecommitdiff
path: root/source3/auth/server_info_sam.c
diff options
context:
space:
mode:
authorVolker Lendecke <vl@samba.org>2010-04-11 22:41:59 +0200
committerVolker Lendecke <vl@samba.org>2010-04-11 22:59:47 +0200
commit18909879cc100b958d74c78ff9f84e9ba3318340 (patch)
tree6acb46c3470517ee54b6ebcc86f216e2d99d5379 /source3/auth/server_info_sam.c
parent2b1a50c2e537f690acd8eff1d0cf3102104144d3 (diff)
downloadsamba-18909879cc100b958d74c78ff9f84e9ba3318340.tar.gz
samba-18909879cc100b958d74c78ff9f84e9ba3318340.tar.bz2
samba-18909879cc100b958d74c78ff9f84e9ba3318340.zip
s3: Move make_server_info_sam to auth/server_info_sam.c
Diffstat (limited to 'source3/auth/server_info_sam.c')
-rw-r--r--source3/auth/server_info_sam.c151
1 files changed, 151 insertions, 0 deletions
diff --git a/source3/auth/server_info_sam.c b/source3/auth/server_info_sam.c
new file mode 100644
index 0000000000..c6e7522011
--- /dev/null
+++ b/source3/auth/server_info_sam.c
@@ -0,0 +1,151 @@
+/*
+ Unix SMB/CIFS implementation.
+ Authentication utility functions
+ Copyright (C) Andrew Tridgell 1992-1998
+ Copyright (C) Andrew Bartlett 2001
+ Copyright (C) Jeremy Allison 2000-2001
+ Copyright (C) Rafal Szczesniak 2002
+ Copyright (C) Volker Lendecke 2006
+
+ 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "includes.h"
+#include "smbd/globals.h"
+#include "../libcli/auth/libcli_auth.h"
+
+#undef DBGC_CLASS
+#define DBGC_CLASS DBGC_AUTH
+
+
+/***************************************************************************
+ Is the incoming username our own machine account ?
+ If so, the connection is almost certainly from winbindd.
+***************************************************************************/
+
+static bool is_our_machine_account(const char *username)
+{
+ bool ret;
+ char *truncname = NULL;
+ size_t ulen = strlen(username);
+
+ if (ulen == 0 || username[ulen-1] != '$') {
+ return false;
+ }
+ truncname = SMB_STRDUP(username);
+ if (!truncname) {
+ return false;
+ }
+ truncname[ulen-1] = '\0';
+ ret = strequal(truncname, global_myname());
+ SAFE_FREE(truncname);
+ return ret;
+}
+
+/***************************************************************************
+ Make (and fill) a user_info struct from a struct samu
+***************************************************************************/
+
+NTSTATUS make_server_info_sam(struct auth_serversupplied_info **server_info,
+ struct samu *sampass)
+{
+ struct passwd *pwd;
+ gid_t *gids;
+ struct auth_serversupplied_info *result;
+ const char *username = pdb_get_username(sampass);
+ NTSTATUS status;
+
+ if ( !(result = make_server_info(NULL)) ) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ if ( !(pwd = getpwnam_alloc(result, username)) ) {
+ DEBUG(1, ("User %s in passdb, but getpwnam() fails!\n",
+ pdb_get_username(sampass)));
+ TALLOC_FREE(result);
+ return NT_STATUS_NO_SUCH_USER;
+ }
+
+ result->sam_account = sampass;
+ result->unix_name = pwd->pw_name;
+ /* Ensure that we keep pwd->pw_name, because we will free pwd below */
+ talloc_steal(result, pwd->pw_name);
+ result->utok.gid = pwd->pw_gid;
+ result->utok.uid = pwd->pw_uid;
+
+ TALLOC_FREE(pwd);
+
+ result->sanitized_username = sanitize_username(result,
+ result->unix_name);
+ if (result->sanitized_username == NULL) {
+ TALLOC_FREE(result);
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ if (IS_DC && is_our_machine_account(username)) {
+ /*
+ * Ensure for a connection from our own
+ * machine account (from winbindd on a DC)
+ * there are no supplementary groups.
+ * Prevents loops in calling gid_to_sid().
+ */
+ result->sids = NULL;
+ gids = NULL;
+ result->num_sids = 0;
+
+ /*
+ * This is a hack of monstrous proportions.
+ * If we know it's winbindd talking to us,
+ * we know we must never recurse into it,
+ * so turn off contacting winbindd for this
+ * entire process. This will get fixed when
+ * winbindd doesn't need to talk to smbd on
+ * a PDC. JRA.
+ */
+
+ (void)winbind_off();
+
+ DEBUG(10, ("make_server_info_sam: our machine account %s "
+ "setting supplementary group list empty and "
+ "turning off winbindd requests.\n",
+ username));
+ } else {
+ 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)));
+ result->sam_account = NULL; /* Don't free on error exit. */
+ 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);
+
+ DEBUG(5,("make_server_info_sam: made server info for user %s -> %s\n",
+ pdb_get_username(sampass), result->unix_name));
+
+ *server_info = result;
+ /* Ensure that the sampass will be freed with the result */
+ talloc_steal(result, sampass);
+
+ return NT_STATUS_OK;
+}