summaryrefslogtreecommitdiffstats
path: root/source3/auth
diff options
context:
space:
mode:
authorAndreas Schneider <asn@samba.org>2013-12-13 19:08:34 +0100
committerAndrew Bartlett <abartlet@samba.org>2014-02-05 11:41:25 +1300
commit1bb11c7744df6928cb8a096373ab920366b38770 (patch)
tree83399b5b5a22e594d6e6b27911c0d7938c91e44c /source3/auth
parent241e98d8ee099f9cc5feb835085b4abd2b1ee663 (diff)
downloadsamba-1bb11c7744df6928cb8a096373ab920366b38770.tar.gz
samba-1bb11c7744df6928cb8a096373ab920366b38770.tar.xz
samba-1bb11c7744df6928cb8a096373ab920366b38770.zip
s3-auth: Add passwd_to_SamInfo3().
First this function tries to contacts winbind if the user is a domain user to get valid information about it. If winbind isn't running it will try to create everything from the passwd struct. This is not always reliable but works in most cases. It improves the current situation which doesn't talk to winbind at all. Pair-Programmed-With: Guenther Deschner <gd@samba.org> Signed-off-by: Guenther Deschner <gd@samba.org> Signed-off-by: Andreas Schneider <asn@samba.org> Reviewed-by: Andrew Bartlett <abartlet@samba.org>
Diffstat (limited to 'source3/auth')
-rw-r--r--source3/auth/proto.h4
-rw-r--r--source3/auth/server_info.c116
2 files changed, 120 insertions, 0 deletions
diff --git a/source3/auth/proto.h b/source3/auth/proto.h
index 76661fc833..8385e66582 100644
--- a/source3/auth/proto.h
+++ b/source3/auth/proto.h
@@ -286,6 +286,10 @@ NTSTATUS samu_to_SamInfo3(TALLOC_CTX *mem_ctx,
const char *login_server,
struct netr_SamInfo3 **_info3,
struct extra_auth_info *extra);
+NTSTATUS passwd_to_SamInfo3(TALLOC_CTX *mem_ctx,
+ const char *unix_username,
+ const struct passwd *pwd,
+ struct netr_SamInfo3 **pinfo3);
struct netr_SamInfo3 *copy_netr_SamInfo3(TALLOC_CTX *mem_ctx,
struct netr_SamInfo3 *orig);
struct netr_SamInfo3 *wbcAuthUserInfo_to_netr_SamInfo3(TALLOC_CTX *mem_ctx,
diff --git a/source3/auth/server_info.c b/source3/auth/server_info.c
index d2b7d6e938..46d817880a 100644
--- a/source3/auth/server_info.c
+++ b/source3/auth/server_info.c
@@ -24,6 +24,7 @@
#include "../libcli/security/security.h"
#include "rpc_client/util_netlogon.h"
#include "nsswitch/libwbclient/wbclient.h"
+#include "lib/winbind_util.h"
#include "passdb.h"
#undef DBGC_CLASS
@@ -436,6 +437,121 @@ NTSTATUS samu_to_SamInfo3(TALLOC_CTX *mem_ctx,
return NT_STATUS_OK;
}
+NTSTATUS passwd_to_SamInfo3(TALLOC_CTX *mem_ctx,
+ const char *unix_username,
+ const struct passwd *pwd,
+ struct netr_SamInfo3 **pinfo3)
+{
+ struct netr_SamInfo3 *info3;
+ NTSTATUS status;
+ TALLOC_CTX *tmp_ctx;
+ const char *domain_name = NULL;
+ const char *user_name = NULL;
+ struct dom_sid domain_sid;
+ struct dom_sid user_sid;
+ struct dom_sid group_sid;
+ enum lsa_SidType type;
+ uint32_t num_sids = 0;
+ struct dom_sid *user_sids = NULL;
+ bool ok;
+
+ tmp_ctx = talloc_stackframe();
+
+ ok = lookup_name_smbconf(tmp_ctx,
+ unix_username,
+ LOOKUP_NAME_ALL,
+ &domain_name,
+ &user_name,
+ &user_sid,
+ &type);
+ if (!ok) {
+ status = NT_STATUS_NO_SUCH_USER;
+ goto done;
+ }
+
+ if (type != SID_NAME_USER) {
+ status = NT_STATUS_NO_SUCH_USER;
+ goto done;
+ }
+
+ ok = winbind_lookup_usersids(tmp_ctx,
+ &user_sid,
+ &num_sids,
+ &user_sids);
+ /* Check if winbind is running */
+ if (ok) {
+ /*
+ * Winbind is running and the first element of the user_sids
+ * is the primary group.
+ */
+ if (num_sids > 0) {
+ group_sid = user_sids[0];
+ }
+ } else {
+ /*
+ * Winbind is not running, create the group_sid from the
+ * group id.
+ */
+ gid_to_sid(&group_sid, pwd->pw_gid);
+ }
+
+ /* Make sure we have a valid group sid */
+ ok = !is_null_sid(&group_sid);
+ if (!ok) {
+ status = NT_STATUS_NO_SUCH_USER;
+ goto done;
+ }
+
+ /* Construct a netr_SamInfo3 from the information we have */
+ info3 = talloc_zero(tmp_ctx, struct netr_SamInfo3);
+ if (!info3) {
+ status = NT_STATUS_NO_MEMORY;
+ goto done;
+ }
+
+ info3->base.account_name.string = talloc_strdup(info3, unix_username);
+ if (info3->base.account_name.string == NULL) {
+ status = NT_STATUS_NO_MEMORY;
+ goto done;
+ }
+
+ ZERO_STRUCT(domain_sid);
+
+ sid_copy(&domain_sid, &user_sid);
+ sid_split_rid(&domain_sid, &info3->base.rid);
+ info3->base.domain_sid = dom_sid_dup(info3, &domain_sid);
+
+ 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;
+ }
+
+ info3->base.acct_flags = ACB_NORMAL;
+
+ if (num_sids) {
+ status = group_sids_to_info3(info3, user_sids, num_sids);
+ if (!NT_STATUS_IS_OK(status)) {
+ goto done;
+ }
+ }
+
+ *pinfo3 = talloc_steal(mem_ctx, info3);
+
+ status = NT_STATUS_OK;
+done:
+ talloc_free(tmp_ctx);
+
+ return status;
+}
+
#undef RET_NOMEM
#define RET_NOMEM(ptr) do { \