Esempio n. 1
0
/**
 * Create the requested BUILTIN if it doesn't already exist.  This requires
 * winbindd to be running.
 *
 * @param[in] rid BUILTIN rid to create
 * @return Normal NTSTATUS return.
 */
static NTSTATUS create_builtin(uint32 rid)
{
	NTSTATUS status = NT_STATUS_OK;
	struct dom_sid sid;
	gid_t gid;

	if (!sid_compose(&sid, &global_sid_Builtin, rid)) {
		return NT_STATUS_NO_SUCH_ALIAS;
	}

	if (!sid_to_gid(&sid, &gid)) {
		if (!lp_winbind_nested_groups() || !winbind_ping()) {
			return NT_STATUS_PROTOCOL_UNREACHABLE;
		}
		status = pdb_create_builtin_alias(rid);
	}
	return status;
}
Esempio n. 2
0
NTSTATUS create_local_token(struct auth_serversupplied_info *server_info)
{
	struct security_token *t;
	NTSTATUS status;
	size_t i;
	struct dom_sid tmp_sid;
	struct wbcUnixId *ids;

	/*
	 * If winbind is not around, we can not make much use of the SIDs the
	 * domain controller provided us with. Likewise if the user name was
	 * mapped to some local unix user.
	 */

	if (((lp_server_role() == ROLE_DOMAIN_MEMBER) && !winbind_ping()) ||
	    (server_info->nss_token)) {
		status = create_token_from_username(server_info,
						    server_info->unix_name,
						    server_info->guest,
						    &server_info->utok.uid,
						    &server_info->utok.gid,
						    &server_info->unix_name,
						    &server_info->security_token);

	} else {
		status = create_local_nt_token_from_info3(server_info,
							  server_info->guest,
							  server_info->info3,
							  &server_info->extra,
							  &server_info->security_token);
	}

	if (!NT_STATUS_IS_OK(status)) {
		return status;
	}

	/* Convert the SIDs to gids. */

	server_info->utok.ngroups = 0;
	server_info->utok.groups = NULL;

	t = server_info->security_token;

	ids = TALLOC_ARRAY(talloc_tos(), struct wbcUnixId,
			   t->num_sids);
	if (ids == NULL) {
		return NT_STATUS_NO_MEMORY;
	}

	if (!sids_to_unix_ids(t->sids, t->num_sids, ids)) {
		TALLOC_FREE(ids);
		return NT_STATUS_NO_MEMORY;
	}

	/* Start at index 1, where the groups start. */

	for (i=1; i<t->num_sids; i++) {

		if (ids[i].type != WBC_ID_TYPE_GID) {
			DEBUG(10, ("Could not convert SID %s to gid, "
				   "ignoring it\n",
				   sid_string_dbg(&t->sids[i])));
			continue;
		}
		if (!add_gid_to_array_unique(server_info, ids[i].id.gid,
					     &server_info->utok.groups,
					     &server_info->utok.ngroups)) {
			return NT_STATUS_NO_MEMORY;
		}
	}

	/*
	 * Add the "Unix Group" SID for each gid to catch mapped groups
	 * and their Unix equivalent.  This is to solve the backwards
	 * compatibility problem of 'valid users = +ntadmin' where
	 * ntadmin has been paired with "Domain Admins" in the group
	 * mapping table.  Otherwise smb.conf would need to be changed
	 * to 'valid user = "******"'.  --jerry
	 *
	 * For consistency we also add the "Unix User" SID,
	 * so that the complete unix token is represented within
	 * the nt token.
	 */

	uid_to_unix_users_sid(server_info->utok.uid, &tmp_sid);

	add_sid_to_array_unique(server_info->security_token, &tmp_sid,
				&server_info->security_token->sids,
				&server_info->security_token->num_sids);

	for ( i=0; i<server_info->utok.ngroups; i++ ) {
		gid_to_unix_groups_sid(server_info->utok.groups[i], &tmp_sid);
		add_sid_to_array_unique(server_info->security_token, &tmp_sid,
					&server_info->security_token->sids,
					&server_info->security_token->num_sids);
	}

	security_token_debug(DBGC_AUTH, 10, server_info->security_token);
	debug_unix_user_token(DBGC_AUTH, 10,
			      server_info->utok.uid,
			      server_info->utok.gid,
			      server_info->utok.ngroups,
			      server_info->utok.groups);

	status = log_nt_token(server_info->security_token);
	return status;
}
Esempio n. 3
0
struct passwd *smb_getpwnam( TALLOC_CTX *mem_ctx, const char *domuser,
			     char **p_save_username, bool create )
{
	struct passwd *pw = NULL;
	char *p = NULL;
	char *username = NULL;

	/* we only save a copy of the username it has been mangled 
	   by winbindd use default domain */
	*p_save_username = NULL;

	/* don't call map_username() here since it has to be done higher 
	   up the stack so we don't call it multiple times */

	username = talloc_strdup(mem_ctx, domuser);
	if (!username) {
		return NULL;
	}

	p = strchr_m( username, *lp_winbind_separator() );

	/* code for a DOMAIN\user string */

	if ( p ) {
		pw = Get_Pwnam_alloc( mem_ctx, domuser );
		if ( pw ) {
			/* make sure we get the case of the username correct */
			/* work around 'winbind use default domain = yes' */

			if ( lp_winbind_use_default_domain() &&
			     !strchr_m( pw->pw_name, *lp_winbind_separator() ) ) {
				char *domain;

				/* split the domain and username into 2 strings */
				*p = '\0';
				domain = username;

				*p_save_username = talloc_asprintf(mem_ctx,
								"%s%c%s",
								domain,
								*lp_winbind_separator(),
								pw->pw_name);
				if (!*p_save_username) {
					TALLOC_FREE(pw);
					return NULL;
				}
			} else {
				*p_save_username = talloc_strdup(mem_ctx, pw->pw_name);
			}

			/* whew -- done! */
			return pw;
		}

		/* setup for lookup of just the username */
		/* remember that p and username are overlapping memory */

		p++;
		username = talloc_strdup(mem_ctx, p);
		if (!username) {
			return NULL;
		}
	}

	/* just lookup a plain username */

	pw = Get_Pwnam_alloc(mem_ctx, username);

	/* Create local user if requested but only if winbindd
	   is not running.  We need to protect against cases
	   where winbindd is failing and then prematurely
	   creating users in /etc/passwd */

	if ( !pw && create && !winbind_ping() ) {
		/* Don't add a machine account. */
		if (username[strlen(username)-1] == '$')
			return NULL;

		_smb_create_user(NULL, username, NULL);
		pw = Get_Pwnam_alloc(mem_ctx, username);
	}

	/* one last check for a valid passwd struct */

	if (pw) {
		*p_save_username = talloc_strdup(mem_ctx, pw->pw_name);
	}
	return pw;
}
Esempio n. 4
0
BOOL winbindd_running(void)
{
	return winbind_ping();
}	
Esempio n. 5
0
NTSTATUS create_local_token(TALLOC_CTX *mem_ctx,
			    const struct auth_serversupplied_info *server_info,
			    DATA_BLOB *session_key,
			    const char *smb_username, /* for ->sanitized_username, for %U subs */
			    struct auth_session_info **session_info_out)
{
	struct security_token *t;
	NTSTATUS status;
	size_t i;
	struct dom_sid tmp_sid;
	struct auth_session_info *session_info;
	struct unixid *ids;
	fstring tmp;

	/* Ensure we can't possible take a code path leading to a
	 * null defref. */
	if (!server_info) {
		return NT_STATUS_LOGON_FAILURE;
	}

	session_info = talloc_zero(mem_ctx, struct auth_session_info);
	if (!session_info) {
		return NT_STATUS_NO_MEMORY;
	}

	session_info->unix_token = talloc_zero(session_info, struct security_unix_token);
	if (!session_info->unix_token) {
		TALLOC_FREE(session_info);
		return NT_STATUS_NO_MEMORY;
	}

	session_info->unix_token->uid = server_info->utok.uid;
	session_info->unix_token->gid = server_info->utok.gid;

	session_info->unix_info = talloc_zero(session_info, struct auth_user_info_unix);
	if (!session_info->unix_info) {
		TALLOC_FREE(session_info);
		return NT_STATUS_NO_MEMORY;
	}

	session_info->unix_info->unix_name = talloc_strdup(session_info, server_info->unix_name);
	if (!session_info->unix_info->unix_name) {
		TALLOC_FREE(session_info);
		return NT_STATUS_NO_MEMORY;
	}

	/* This is a potentially untrusted username for use in %U */
	alpha_strcpy(tmp, smb_username, ". _-$", sizeof(tmp));
	session_info->unix_info->sanitized_username =
				talloc_strdup(session_info->unix_info, tmp);

	if (session_key) {
		data_blob_free(&session_info->session_key);
		session_info->session_key = data_blob_talloc(session_info,
								  session_key->data,
								  session_key->length);
		if (!session_info->session_key.data && session_key->length) {
			return NT_STATUS_NO_MEMORY;
		}
	} else {
		session_info->session_key = data_blob_talloc( session_info, server_info->session_key.data,
							      server_info->session_key.length);
	}

	/* We need to populate session_info->info with the information found in server_info->info3 */
	status = make_user_info_SamBaseInfo(session_info, "", &server_info->info3->base,
					    server_info->guest == false,
					    &session_info->info);
	if (!NT_STATUS_IS_OK(status)) {
		DEBUG(0, ("conversion of info3 into auth_user_info failed!\n"));
		TALLOC_FREE(session_info);
		return status;
	}

	if (server_info->security_token) {
		/* Just copy the token, it has already been finalised
		 * (nasty hack to support a cached guest/system session_info
		 */

		session_info->security_token = dup_nt_token(session_info, server_info->security_token);
		if (!session_info->security_token) {
			TALLOC_FREE(session_info);
			return NT_STATUS_NO_MEMORY;
		}

		session_info->unix_token->ngroups = server_info->utok.ngroups;
		if (server_info->utok.ngroups != 0) {
			session_info->unix_token->groups = (gid_t *)talloc_memdup(
				session_info->unix_token, server_info->utok.groups,
				sizeof(gid_t)*session_info->unix_token->ngroups);
		} else {
			session_info->unix_token->groups = NULL;
		}

		*session_info_out = session_info;
		return NT_STATUS_OK;
	}

	/*
	 * If winbind is not around, we can not make much use of the SIDs the
	 * domain controller provided us with. Likewise if the user name was
	 * mapped to some local unix user.
	 */

	if (((lp_server_role() == ROLE_DOMAIN_MEMBER) && !winbind_ping()) ||
	    (server_info->nss_token)) {
		char *found_username = NULL;
		status = create_token_from_username(session_info,
						    server_info->unix_name,
						    server_info->guest,
						    &session_info->unix_token->uid,
						    &session_info->unix_token->gid,
						    &found_username,
						    &session_info->security_token);
		if (NT_STATUS_IS_OK(status)) {
			session_info->unix_info->unix_name = found_username;
		}
	} else {
		status = create_local_nt_token_from_info3(session_info,
							  server_info->guest,
							  server_info->info3,
							  &server_info->extra,
							  &session_info->security_token);
	}

	if (!NT_STATUS_IS_OK(status)) {
		return status;
	}

	/* Convert the SIDs to gids. */

	session_info->unix_token->ngroups = 0;
	session_info->unix_token->groups = NULL;

	t = session_info->security_token;

	ids = talloc_array(talloc_tos(), struct unixid,
			   t->num_sids);
	if (ids == NULL) {
		return NT_STATUS_NO_MEMORY;
	}

	if (!sids_to_unixids(t->sids, t->num_sids, ids)) {
		TALLOC_FREE(ids);
		return NT_STATUS_NO_MEMORY;
	}

	for (i=0; i<t->num_sids; i++) {

		if (i == 0 && ids[i].type != ID_TYPE_BOTH) {
			continue;
		}

		if (ids[i].type != ID_TYPE_GID &&
		    ids[i].type != ID_TYPE_BOTH) {
			DEBUG(10, ("Could not convert SID %s to gid, "
				   "ignoring it\n",
				   sid_string_dbg(&t->sids[i])));
			continue;
		}
		if (!add_gid_to_array_unique(session_info, ids[i].id,
					     &session_info->unix_token->groups,
					     &session_info->unix_token->ngroups)) {
			return NT_STATUS_NO_MEMORY;
		}
	}

	/*
	 * Add the "Unix Group" SID for each gid to catch mapped groups
	 * and their Unix equivalent.  This is to solve the backwards
	 * compatibility problem of 'valid users = +ntadmin' where
	 * ntadmin has been paired with "Domain Admins" in the group
	 * mapping table.  Otherwise smb.conf would need to be changed
	 * to 'valid user = "******"'.  --jerry
	 *
	 * For consistency we also add the "Unix User" SID,
	 * so that the complete unix token is represented within
	 * the nt token.
	 */

	uid_to_unix_users_sid(session_info->unix_token->uid, &tmp_sid);

	add_sid_to_array_unique(session_info->security_token, &tmp_sid,
				&session_info->security_token->sids,
				&session_info->security_token->num_sids);

	for ( i=0; i<session_info->unix_token->ngroups; i++ ) {
		gid_to_unix_groups_sid(session_info->unix_token->groups[i], &tmp_sid);
		add_sid_to_array_unique(session_info->security_token, &tmp_sid,
					&session_info->security_token->sids,
					&session_info->security_token->num_sids);
	}

	security_token_debug(DBGC_AUTH, 10, session_info->security_token);
	debug_unix_user_token(DBGC_AUTH, 10,
			      session_info->unix_token->uid,
			      session_info->unix_token->gid,
			      session_info->unix_token->ngroups,
			      session_info->unix_token->groups);

	status = log_nt_token(session_info->security_token);
	if (!NT_STATUS_IS_OK(status)) {
		return status;
	}

	*session_info_out = session_info;
	return NT_STATUS_OK;
}
Esempio n. 6
0
static int net_idmap_restore(struct net_context *c, int argc, const char **argv)
{
	TALLOC_CTX *ctx;
	FILE *input;

	if (c->display_usage) {
		d_printf(_("Usage:\n"
			   "net idmap restore [inputfile]\n"
			   "  Restore ID mappings from file\n"
			   "    inputfile\tFile to load ID mappings from. If "
			   "not given, load data from stdin.\n"));
		return 0;
	}

	if (! winbind_ping()) {
		d_fprintf(stderr,
			  _("To use net idmap Winbindd must be running.\n"));
		return -1;
	}

	ctx = talloc_new(NULL);
	ALLOC_CHECK(ctx);

	if (argc == 1) {
		input = fopen(argv[0], "r");
	} else {
		input = stdin;
	}

	while (!feof(input)) {
		char line[128], sid_string[128];
		int len;
		struct wbcDomainSid sid;
		enum id_type type = ID_TYPE_NOT_SPECIFIED;
		unsigned long idval;
		wbcErr wbc_status;

		if (fgets(line, 127, input) == NULL)
			break;

		len = strlen(line);

		if ( (len > 0) && (line[len-1] == '\n') )
			line[len-1] = '\0';

		if (sscanf(line, "GID %lu %128s", &idval, sid_string) == 2) {
			type = ID_TYPE_GID;
		} else if (sscanf(line, "UID %lu %128s", &idval, sid_string) == 2) {
			type = ID_TYPE_UID;
		} else if (sscanf(line, "USER HWM %lu", &idval) == 1) {
			/* set uid hwm */
			wbc_status = wbcSetUidHwm(idval);
			if (!WBC_ERROR_IS_OK(wbc_status)) {
				d_fprintf(stderr,
					  _("Could not set USER HWM: %s\n"),
					  wbcErrorString(wbc_status));
			}
			continue;
		} else if (sscanf(line, "GROUP HWM %lu", &idval) == 1) {
			/* set gid hwm */
			wbc_status = wbcSetGidHwm(idval);
			if (!WBC_ERROR_IS_OK(wbc_status)) {
				d_fprintf(stderr,
					  _("Could not set GROUP HWM: %s\n"),
					  wbcErrorString(wbc_status));
			}
			continue;
		} else {
			d_fprintf(stderr, _("ignoring invalid line [%s]\n"),
				  line);
			continue;
		}

		wbc_status = wbcStringToSid(sid_string, &sid);
		if (!WBC_ERROR_IS_OK(wbc_status)) {
			d_fprintf(stderr, _("ignoring invalid sid [%s]: %s\n"),
				  sid_string, wbcErrorString(wbc_status));
			continue;
		}

		if (type == ID_TYPE_UID) {
			wbc_status = wbcSetUidMapping(idval, &sid);
		} else {
			wbc_status = wbcSetGidMapping(idval, &sid);
		}
		if (!WBC_ERROR_IS_OK(wbc_status)) {
			d_fprintf(stderr,
				  _("Could not set mapping of %s %lu to sid %s: %s\n"),
				 (type == ID_TYPE_GID) ? "GID" : "UID",
				 idval, sid_string,
				 wbcErrorString(wbc_status));
			continue;
		}
	}

	if (input != stdin) {
		fclose(input);
	}

	talloc_free(ctx);
	return 0;
}