#include "libcli/wbclient/wbclient.h"
#include "param/param.h"
+#undef DBGC_CLASS
+#define DBGC_CLASS DBGC_AUTH
+
/*
form a security_unix_token from the current security_token
*/
NTSTATUS security_token_to_unix_token(TALLOC_CTX *mem_ctx,
- struct tevent_context *ev,
struct security_token *token,
struct security_unix_token **sec)
{
uint32_t s, g;
NTSTATUS status;
struct id_map *ids;
+ bool match;
+
+ match = security_token_is_system(token);
+ if (match) {
+ /*
+ * SYSTEM user uid and gid is 0
+ */
+
+ *sec = talloc_zero(mem_ctx, struct security_unix_token);
+ if (*sec == NULL) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ return NT_STATUS_OK;
+ }
/* we can't do unix security without a user and group */
- if (token->num_sids < 2) {
+ if (token->num_sids < PRIMARY_SIDS_COUNT) {
return NT_STATUS_ACCESS_DENIED;
}
ids[s].status = ID_UNKNOWN;
}
- status = wbc_sids_to_xids(ev, ids, token->num_sids);
+ status = wbc_sids_to_xids(ids, token->num_sids);
NT_STATUS_NOT_OK_RETURN(status);
g = token->num_sids;
- if (ids[0].xid.type != ID_TYPE_BOTH) {
+ if (ids[PRIMARY_USER_SID_INDEX].xid.type != ID_TYPE_BOTH) {
g--;
}
(*sec)->ngroups = g;
NT_STATUS_HAVE_NO_MEMORY((*sec)->groups);
g=0;
- if (ids[0].xid.type == ID_TYPE_BOTH) {
+ if (ids[PRIMARY_USER_SID_INDEX].xid.type == ID_TYPE_BOTH) {
(*sec)->uid = ids[0].xid.id;
(*sec)->groups[g] = ids[0].xid.id;
g++;
- } else if (ids[0].xid.type == ID_TYPE_UID) {
+ } else if (ids[PRIMARY_USER_SID_INDEX].xid.type == ID_TYPE_UID) {
(*sec)->uid = ids[0].xid.id;
} else {
- char *sid_str = dom_sid_string(mem_ctx, ids[0].sid);
+ struct dom_sid_buf buf;
DEBUG(0, ("Unable to convert first SID (%s) in user token to a UID. Conversion was returned as type %d, full token:\n",
- sid_str, (int)ids[0].xid.type));
- security_token_debug(0, 0, token);
- talloc_free(sid_str);
+ dom_sid_str_buf(ids[PRIMARY_USER_SID_INDEX].sid, &buf),
+ (int)ids[PRIMARY_USER_SID_INDEX].xid.type));
+ security_token_debug(DBGC_AUTH, 0, token);
return NT_STATUS_INVALID_SID;
}
- if (ids[1].xid.type == ID_TYPE_BOTH ||
- ids[1].xid.type == ID_TYPE_GID) {
- (*sec)->gid = ids[1].xid.id;
- (*sec)->groups[g] = ids[1].xid.id;
+ if (ids[PRIMARY_GROUP_SID_INDEX].xid.type == ID_TYPE_BOTH ||
+ ids[PRIMARY_GROUP_SID_INDEX].xid.type == ID_TYPE_GID) {
+ (*sec)->gid = ids[PRIMARY_GROUP_SID_INDEX].xid.id;
+ (*sec)->groups[g] = ids[PRIMARY_GROUP_SID_INDEX].xid.id;
g++;
} else {
- char *sid_str = dom_sid_string(mem_ctx, ids[1].sid);
+ struct dom_sid_buf buf;
DEBUG(0, ("Unable to convert second SID (%s) in user token to a GID. Conversion was returned as type %d, full token:\n",
- sid_str, (int)ids[1].xid.type));
- security_token_debug(0, 0, token);
- talloc_free(sid_str);
+ dom_sid_str_buf(ids[PRIMARY_GROUP_SID_INDEX].sid, &buf),
+ (int)ids[PRIMARY_GROUP_SID_INDEX].xid.type));
+ security_token_debug(DBGC_AUTH, 0, token);
return NT_STATUS_INVALID_SID;
}
- for (s=2; s < token->num_sids; s++) {
+ for (s=REMAINING_SIDS_INDEX; s < token->num_sids; s++) {
if (ids[s].xid.type == ID_TYPE_BOTH ||
ids[s].xid.type == ID_TYPE_GID) {
(*sec)->groups[g] = ids[s].xid.id;
g++;
} else {
- char *sid_str = dom_sid_string(mem_ctx, ids[s].sid);
+ struct dom_sid_buf buf;
DEBUG(0, ("Unable to convert SID (%s) at index %u in user token to a GID. Conversion was returned as type %d, full token:\n",
- sid_str, (unsigned int)s, (int)ids[s].xid.type));
- security_token_debug(0, 0, token);
- talloc_free(sid_str);
+ dom_sid_str_buf(ids[s].sid, &buf),
+ (unsigned int)s, (int)ids[s].xid.type));
+ security_token_debug(DBGC_AUTH, 0, token);
return NT_STATUS_INVALID_SID;
}
}
return NT_STATUS_OK;
}
+/*
+ * Fill in the unix_info elements in a struct session_info
+ */
+NTSTATUS fill_unix_info(struct loadparm_context *lp_ctx,
+ const char *original_user_name,
+ struct auth_session_info *session_info)
+{
+ session_info->unix_info = talloc_zero(session_info,
+ struct auth_user_info_unix);
+ NT_STATUS_HAVE_NO_MEMORY(session_info->unix_info);
+
+ session_info->unix_info->unix_name =
+ talloc_asprintf(session_info->unix_info,
+ "%s%s%s", session_info->info->domain_name,
+ lpcfg_winbind_separator(lp_ctx),
+ session_info->info->account_name);
+ NT_STATUS_HAVE_NO_MEMORY(session_info->unix_info->unix_name);
+
+ if (original_user_name == NULL) {
+ original_user_name = session_info->unix_info->unix_name;
+ }
+
+ session_info->unix_info->sanitized_username =
+ talloc_alpha_strcpy(session_info->unix_info,
+ original_user_name,
+ ". _-$");
+ NT_STATUS_HAVE_NO_MEMORY(session_info->unix_info->sanitized_username);
+
+ return NT_STATUS_OK;
+}
+
/*
Fill in the auth_user_info_unix and auth_unix_token elements in a struct session_info
*/
-NTSTATUS auth_session_info_fill_unix(struct wbc_context *wbc_ctx,
- struct loadparm_context *lp_ctx,
+NTSTATUS auth_session_info_fill_unix(struct loadparm_context *lp_ctx,
const char *original_user_name,
struct auth_session_info *session_info)
{
- char *su;
- size_t len;
- NTSTATUS status = security_token_to_unix_token(session_info, wbc_ctx->event_ctx,
- session_info->security_token,
- &session_info->unix_token);
+ NTSTATUS status = NT_STATUS_OK;
+
+ status = security_token_to_unix_token(session_info,
+ session_info->security_token,
+ &session_info->unix_token);
if (!NT_STATUS_IS_OK(status)) {
return status;
}
- session_info->unix_info = talloc_zero(session_info, struct auth_user_info_unix);
- NT_STATUS_HAVE_NO_MEMORY(session_info->unix_info);
+ status = fill_unix_info(lp_ctx,
+ original_user_name,
+ session_info);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
- session_info->unix_info->unix_name = talloc_asprintf(session_info->unix_info,
- "%s%s%s", session_info->info->domain_name,
- lpcfg_winbind_separator(lp_ctx),
- session_info->info->account_name);
- NT_STATUS_HAVE_NO_MEMORY(session_info->unix_info->unix_name);
+ return NT_STATUS_OK;
+}
+
+/*
+ * Set the given auth_user_info_unix and auth_unix_token elements in a
+ * struct session_info, similar auth_session_info_fill_unix().
+ * Receives the uid and gid for the unix token as parameters and does
+ * not query the unix token from winbind (via security_token_to_unix_token()).
+ * This is useful to fill a user session info manually if winbind is not
+ * available.
+ */
+NTSTATUS auth_session_info_set_unix(struct loadparm_context *lp_ctx,
+ const char *original_user_name,
+ int uid,
+ int gid,
+ struct auth_session_info *session_info)
+{
+ NTSTATUS status;
- len = strlen(original_user_name) + 1;
- session_info->unix_info->sanitized_username = su = talloc_array(session_info->unix_info, char, len);
- NT_STATUS_HAVE_NO_MEMORY(su);
+ session_info->unix_token = talloc_zero(session_info,
+ struct security_unix_token);
+ if (session_info->unix_token == NULL) {
+ return NT_STATUS_NO_MEMORY;
+ }
- alpha_strcpy(su, original_user_name,
- ". _-$", len);
+ session_info->unix_token->uid = uid;
+ session_info->unix_token->gid = gid;
+
+ status = fill_unix_info(lp_ctx,
+ original_user_name,
+ session_info);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
return NT_STATUS_OK;
}