Пример #1
0
BOOL map_name_to_wellknown_sid(DOM_SID *sid, enum SID_NAME_USE *use, const char *name)
{
	int i, j;

	if (!sid_name_map_initialized)
		init_sid_name_map();

	DEBUG(10,("map_name_to_wellknown_sid: looking up %s\n", name));

	for (i=0; sid_name_map[i].sid != NULL; i++) {
		const known_sid_users *users = sid_name_map[i].known_users;

		if (users == NULL)
			continue;

		for (j=0; users[j].known_user_name != NULL; j++) {
			if ( strequal(users[j].known_user_name, name) ) {
				sid_copy(sid, sid_name_map[i].sid);
				sid_append_rid(sid, users[j].rid);
				*use = users[j].sid_name_use;
				return True;
			}
		}
	}

	return False;
}
Пример #2
0
bool pdb_set_group_sid(struct samu *sampass, const DOM_SID *g_sid, enum pdb_value_state flag)
{
	gid_t gid;

	if (!g_sid)
		return False;

	if ( !(sampass->group_sid = TALLOC_P( sampass, DOM_SID )) ) {
		return False;
	}

	/* if we cannot resolve the SID to gid, then just ignore it and 
	   store DOMAIN_USERS as the primary groupSID */

	if ( sid_to_gid( g_sid, &gid ) ) {
		sid_copy(sampass->group_sid, g_sid);
	} else {
		sid_copy( sampass->group_sid, get_global_sam_sid() );
		sid_append_rid( sampass->group_sid, DOMAIN_GROUP_RID_USERS );
	}

	DEBUG(10, ("pdb_set_group_sid: setting group sid %s\n", 
		   sid_string_dbg(sampass->group_sid)));

	return pdb_set_init_flags(sampass, PDB_GROUPSID, flag);
}
Пример #3
0
BOOL pdb_set_group_sid_from_rid (struct samu *sampass, uint32 grid, enum pdb_value_state flag)
{
	DOM_SID g_sid;
	const DOM_SID *global_sam_sid;

	if (!sampass)
		return False;
	
	if (!(global_sam_sid = get_global_sam_sid())) {
		DEBUG(1, ("pdb_set_user_sid_from_rid: Could not read global sam sid!\n"));
		return False;
	}

	sid_copy(&g_sid, global_sam_sid);
	
	if (!sid_append_rid(&g_sid, grid))
		return False;

	if (!pdb_set_group_sid(sampass, &g_sid, flag))
		return False;

	DEBUG(10, ("pdb_set_group_sid_from_rid:\n\tsetting group sid %s from rid %d\n", 
		    sid_string_static(&g_sid), grid));

	return True;
}
Пример #4
0
bool string_to_sid(DOM_SID *sidout, const char *sidstr)
{
	const char *p;
	char *q;
	/* BIG NOTE: this function only does SIDS where the identauth is not >= 2^32 */
	uint32 conv;
  
	if ((sidstr[0] != 'S' && sidstr[0] != 's') || sidstr[1] != '-') {
		DEBUG(3,("string_to_sid: Sid %s does not start with 'S-'.\n", sidstr));
		return False;
	}

	ZERO_STRUCTP(sidout);

	/* Get the revision number. */
	p = sidstr + 2;
	conv = (uint32) strtoul(p, &q, 10);
	if (!q || (*q != '-')) {
		DEBUG(3,("string_to_sid: Sid %s is not in a valid format.\n", sidstr));
		return False;
	}
	sidout->sid_rev_num = (uint8) conv;
	q++;

	/* get identauth */
	conv = (uint32) strtoul(q, &q, 10);
	if (!q || (*q != '-')) {
		DEBUG(0,("string_to_sid: Sid %s is not in a valid format.\n", sidstr));
		return False;
	}
	/* identauth in decimal should be <  2^32 */
	/* NOTE - the conv value is in big-endian format. */
	sidout->id_auth[0] = 0;
	sidout->id_auth[1] = 0;
	sidout->id_auth[2] = (conv & 0xff000000) >> 24;
	sidout->id_auth[3] = (conv & 0x00ff0000) >> 16;
	sidout->id_auth[4] = (conv & 0x0000ff00) >> 8;
	sidout->id_auth[5] = (conv & 0x000000ff);

	q++;
	sidout->num_auths = 0;

	for(conv = (uint32) strtoul(q, &q, 10);
	    q && (*q =='-' || *q =='\0') && (sidout->num_auths < MAXSUBAUTHS);
	    conv = (uint32) strtoul(q, &q, 10)) {
		sid_append_rid(sidout, conv);
		if (*q == '\0')
			break;
		q++;
	}
		
	return True;
}
Пример #5
0
bool lookup_unix_group_name(const char *name, DOM_SID *sid)
{
	struct group *grp;

	grp = sys_getgrnam(name);
	if (grp == NULL) {
		return False;
	}

	sid_copy(sid, &global_sid_Unix_Groups);
	sid_append_rid(sid, (uint32_t)grp->gr_gid); /* For 64-bit uid's we have enough
					   * space ... */
	return True;
}
Пример #6
0
bool lookup_unix_user_name(const char *name, DOM_SID *sid)
{
	struct passwd *pwd;

	pwd = Get_Pwnam_alloc(talloc_autofree_context(), name);
	if (pwd == NULL) {
		return False;
	}

	sid_copy(sid, &global_sid_Unix_Users);
	sid_append_rid(sid, (uint32_t)pwd->pw_uid); /* For 64-bit uid's we have enough
					  * space ... */
	TALLOC_FREE(pwd);
	return True;
}
Пример #7
0
/*
  add a rid to a domain dom_sid to make a full dom_sid. This function
  returns a new sid in the supplied memory context
*/
struct dom_sid *dom_sid_add_rid(TALLOC_CTX *mem_ctx,
				const struct dom_sid *domain_sid,
				uint32_t rid)
{
	struct dom_sid *sid;

	sid = dom_sid_dup(mem_ctx, domain_sid);
	if (!sid) return NULL;

	if (!sid_append_rid(sid, rid)) {
		talloc_free(sid);
		return NULL;
	}

	return sid;
}
Пример #8
0
static NTSTATUS check_info3_in_group(TALLOC_CTX *mem_ctx, 
				     NET_USER_INFO_3 *info3,
				     const char *group_sid) 
{
	DOM_SID required_membership_sid;
	DOM_SID *all_sids;
	size_t num_all_sids = (2 + info3->num_groups2 + info3->num_other_sids);
	size_t i, j = 0;

	/* Parse the 'required group' SID */
	
	if (!group_sid || !group_sid[0]) {
		/* NO sid supplied, all users may access */
		return NT_STATUS_OK;
	}
	
	if (!string_to_sid(&required_membership_sid, group_sid)) {
		DEBUG(0, ("check_info3_in_group: could not parse %s as a SID!", 
			  group_sid));

		return NT_STATUS_INVALID_PARAMETER;
	}

	all_sids = talloc(mem_ctx, sizeof(DOM_SID) * num_all_sids);
	if (!all_sids)
		return NT_STATUS_NO_MEMORY;

	/* and create (by appending rids) the 'domain' sids */
	
	sid_copy(&all_sids[0], &(info3->dom_sid.sid));
	
	if (!sid_append_rid(&all_sids[0], info3->user_rid)) {
		DEBUG(3,("could not append user's primary RID 0x%x\n",
			 info3->user_rid));			
		
		return NT_STATUS_INVALID_PARAMETER;
	}
	j++;

	sid_copy(&all_sids[1], &(info3->dom_sid.sid));
		
	if (!sid_append_rid(&all_sids[1], info3->group_rid)) {
		DEBUG(3,("could not append additional group rid 0x%x\n",
			 info3->group_rid));			
		
		return NT_STATUS_INVALID_PARAMETER;
	}
	j++;	

	for (i = 0; i < info3->num_groups2; i++) {
	
		sid_copy(&all_sids[j], &(info3->dom_sid.sid));
		
		if (!sid_append_rid(&all_sids[j], info3->gids[j].g_rid)) {
			DEBUG(3,("could not append additional group rid 0x%x\n",
				info3->gids[j].g_rid));			
				
			return NT_STATUS_INVALID_PARAMETER;
		}
		j++;
	}

	/* Copy 'other' sids.  We need to do sid filtering here to
 	   prevent possible elevation of privileges.  See:

           http://www.microsoft.com/windows2000/techinfo/administration/security/sidfilter.asp
         */

	for (i = 0; i < info3->num_other_sids; i++) {
		sid_copy(&all_sids[info3->num_groups2 + i + 2],
			 &info3->other_sids[j].sid);
		j++;
	}

	for (i = 0; i < j; i++) {
		fstring sid1, sid2;
		DEBUG(10, ("User has SID: %s\n", 
			   sid_to_string(sid1, &all_sids[i])));
		if (sid_equal(&required_membership_sid, &all_sids[i])) {
			DEBUG(10, ("SID %s matches %s - user permitted to authenticate!\n", 
				   sid_to_string(sid1, &required_membership_sid), sid_to_string(sid2, &all_sids[i])));
			return NT_STATUS_OK;
		}
	}
	
	/* Do not distinguish this error from a wrong username/pw */

	return NT_STATUS_LOGON_FAILURE;
}
Пример #9
0
/*********************************************************
 Add New User
**********************************************************/
static int new_user (struct pdb_methods *in, const char *username,
			const char *fullname, const char *homedir,
			const char *drive, const char *script,
			const char *profile, char *user_sid, BOOL stdin_get)
{
	struct samu *sam_pwent;
	char *password1, *password2;
	int rc_pwd_cmp;
	struct passwd *pwd;

	get_global_sam_sid();

	if ( !(pwd = getpwnam_alloc( NULL, username )) ) {
		DEBUG(0,("Cannot locate Unix account for %s\n", username));
		return -1;
	}

	if ( (sam_pwent = samu_new( NULL )) == NULL ) {
		DEBUG(0, ("Memory allocation failure!\n"));
		return -1;
	}

	if (!NT_STATUS_IS_OK(samu_alloc_rid_unix(sam_pwent, pwd ))) {
		TALLOC_FREE( sam_pwent );
		TALLOC_FREE( pwd );
		DEBUG(0, ("could not create account to add new user %s\n", username));
		return -1;
	}

	password1 = get_pass( "new password:"******"retype new password:"******"Passwords do not match!\n");
		TALLOC_FREE(sam_pwent);
	} else {
		pdb_set_plaintext_passwd(sam_pwent, password1);
	}

	memset(password1, 0, strlen(password1));
	SAFE_FREE(password1);
	memset(password2, 0, strlen(password2));
	SAFE_FREE(password2);

	/* pwds do _not_ match? */
	if (rc_pwd_cmp)
		return -1;

	if (fullname)
		pdb_set_fullname(sam_pwent, fullname, PDB_CHANGED);
	if (homedir)
		pdb_set_homedir (sam_pwent, homedir, PDB_CHANGED);
	if (drive)
		pdb_set_dir_drive (sam_pwent, drive, PDB_CHANGED);
	if (script)
		pdb_set_logon_script(sam_pwent, script, PDB_CHANGED);
	if (profile)
		pdb_set_profile_path (sam_pwent, profile, PDB_CHANGED);
	if (user_sid) {
		DOM_SID u_sid;
		if (!string_to_sid(&u_sid, user_sid)) {
			/* not a complete sid, may be a RID, try building a SID */
			int u_rid;
			
			if (sscanf(user_sid, "%d", &u_rid) != 1) {
				fprintf(stderr, "Error passed string is not a complete user SID or RID!\n");
				TALLOC_FREE(sam_pwent);
				return -1;
			}
			sid_copy(&u_sid, get_global_sam_sid());
			sid_append_rid(&u_sid, u_rid);
		}
		pdb_set_user_sid (sam_pwent, &u_sid, PDB_CHANGED);
	}
	
	pdb_set_acct_ctrl (sam_pwent, ACB_NORMAL, PDB_CHANGED);
	
	if (NT_STATUS_IS_OK(in->add_sam_account (in, sam_pwent))) { 
		print_user_info (in, username, True, False);
	} else {
		fprintf (stderr, "Unable to add user! (does it already exist?)\n");
		TALLOC_FREE(sam_pwent);
		return -1;
	}
	TALLOC_FREE(sam_pwent);
	return 0;
}
Пример #10
0
static int set_user_info (struct pdb_methods *in, const char *username, 
			  const char *fullname, const char *homedir, 
			  const char *acct_desc, 
			  const char *drive, const char *script, 
			  const char *profile, const char *account_control,
			  const char *user_sid, const char *user_domain,
			  const BOOL badpw, const BOOL hours)
{
	BOOL updated_autolock = False, updated_badpw = False;
	struct samu *sam_pwent=NULL;
	BOOL ret;
	
	if ( (sam_pwent = samu_new( NULL )) == NULL ) {
		return 1;
	}
	
	ret = NT_STATUS_IS_OK(in->getsampwnam (in, sam_pwent, username));
	if (ret==False) {
		fprintf (stderr, "Username not found!\n");
		TALLOC_FREE(sam_pwent);
		return -1;
	}

	if (hours) {
		uint8 hours_array[MAX_HOURS_LEN];
		uint32 hours_len;
		
		hours_len = pdb_get_hours_len(sam_pwent);
		memset(hours_array, 0xff, hours_len);
		
		pdb_set_hours(sam_pwent, hours_array, PDB_CHANGED);
	}

	if (!pdb_update_autolock_flag(sam_pwent, &updated_autolock)) {
		DEBUG(2,("pdb_update_autolock_flag failed.\n"));
	}

	if (!pdb_update_bad_password_count(sam_pwent, &updated_badpw)) {
		DEBUG(2,("pdb_update_bad_password_count failed.\n"));
	}

	if (fullname)
		pdb_set_fullname(sam_pwent, fullname, PDB_CHANGED);
	if (acct_desc)
		pdb_set_acct_desc(sam_pwent, acct_desc, PDB_CHANGED);
	if (homedir)
		pdb_set_homedir(sam_pwent, homedir, PDB_CHANGED);
	if (drive)
		pdb_set_dir_drive(sam_pwent,drive, PDB_CHANGED);
	if (script)
		pdb_set_logon_script(sam_pwent, script, PDB_CHANGED);
	if (profile)
		pdb_set_profile_path (sam_pwent, profile, PDB_CHANGED);
	if (user_domain)
		pdb_set_domain(sam_pwent, user_domain, PDB_CHANGED);

	if (account_control) {
		uint32 not_settable = ~(ACB_DISABLED|ACB_HOMDIRREQ|ACB_PWNOTREQ|
					ACB_PWNOEXP|ACB_AUTOLOCK);

		uint32 newflag = pdb_decode_acct_ctrl(account_control);

		if (newflag & not_settable) {
			fprintf(stderr, "Can only set [NDHLX] flags\n");
			TALLOC_FREE(sam_pwent);
			return -1;
		}

		pdb_set_acct_ctrl(sam_pwent,
				  (pdb_get_acct_ctrl(sam_pwent) & not_settable) | newflag,
				  PDB_CHANGED);
	}
	if (user_sid) {
		DOM_SID u_sid;
		if (!string_to_sid(&u_sid, user_sid)) {
			/* not a complete sid, may be a RID, try building a SID */
			int u_rid;
			
			if (sscanf(user_sid, "%d", &u_rid) != 1) {
				fprintf(stderr, "Error passed string is not a complete user SID or RID!\n");
				return -1;
			}
			sid_copy(&u_sid, get_global_sam_sid());
			sid_append_rid(&u_sid, u_rid);
		}
		pdb_set_user_sid (sam_pwent, &u_sid, PDB_CHANGED);
	}

	if (badpw) {
		pdb_set_bad_password_count(sam_pwent, 0, PDB_CHANGED);
		pdb_set_bad_password_time(sam_pwent, 0, PDB_CHANGED);
	}

	if (NT_STATUS_IS_OK(in->update_sam_account (in, sam_pwent)))
		print_user_info (in, username, True, False);
	else {
		fprintf (stderr, "Unable to modify entry!\n");
		TALLOC_FREE(sam_pwent);
		return -1;
	}
	TALLOC_FREE(sam_pwent);
	return 0;
}
Пример #11
0
bool uid_to_unix_users_sid(uid_t uid, DOM_SID *sid)
{
	sid_copy(sid, &global_sid_Unix_Users);
	return sid_append_rid(sid, (uint32_t)uid);
}
Пример #12
0
bool gid_to_unix_groups_sid(gid_t gid, DOM_SID *sid)
{
	sid_copy(sid, &global_sid_Unix_Groups);
	return sid_append_rid(sid, (uint32_t)gid);
}
Пример #13
0
bool sid_compose(DOM_SID *dst, const DOM_SID *domain_sid, uint32 rid)
{
	sid_copy(dst, domain_sid);
	return sid_append_rid(dst, rid);
}
Пример #14
0
NTSTATUS pdb_default_create_alias(struct pdb_methods *methods,
				  const char *name, uint32 *rid)
{
	DOM_SID sid;
	enum lsa_SidType type;
	uint32 new_rid;
	gid_t gid;
	bool exists;
	GROUP_MAP map;
	TALLOC_CTX *mem_ctx;
	NTSTATUS status;

	DEBUG(10, ("Trying to create alias %s\n", name));

	mem_ctx = talloc_new(NULL);
	if (mem_ctx == NULL) {
		return NT_STATUS_NO_MEMORY;
	}

	exists = lookup_name(mem_ctx, name, LOOKUP_NAME_LOCAL,
			     NULL, NULL, &sid, &type);
	TALLOC_FREE(mem_ctx);

	if (exists) {
		return NT_STATUS_ALIAS_EXISTS;
	}

	if (!winbind_allocate_gid(&gid)) {
		DEBUG(3, ("Could not get a gid out of winbind\n"));
		return NT_STATUS_ACCESS_DENIED;
	}

	if (!pdb_new_rid(&new_rid)) {
		DEBUG(0, ("Could not allocate a RID -- wasted a gid :-(\n"));
		return NT_STATUS_ACCESS_DENIED;
	}

	DEBUG(10, ("Creating alias %s with gid %d and rid %d\n",
		   name, gid, new_rid));

	sid_copy(&sid, get_global_sam_sid());
	sid_append_rid(&sid, new_rid);

	map.gid = gid;
	sid_copy(&map.sid, &sid);
	map.sid_name_use = SID_NAME_ALIAS;
	fstrcpy(map.nt_name, name);
	fstrcpy(map.comment, "");

	status = pdb_add_group_mapping_entry(&map);

	if (!NT_STATUS_IS_OK(status)) {
		DEBUG(0, ("Could not add group mapping entry for alias %s "
			  "(%s)\n", name, nt_errstr(status)));
		return status;
	}

	*rid = new_rid;

	return NT_STATUS_OK;
}
Пример #15
0
const DOM_SID *pdb_get_group_sid(struct samu *sampass)
{
	DOM_SID *gsid;
	struct passwd *pwd;
	
	/* Return the cached group SID if we have that */
	if ( sampass->group_sid ) {
		return sampass->group_sid;
	}
		
	/* generate the group SID from the user's primary Unix group */
	
	if ( !(gsid  = TALLOC_P( sampass, DOM_SID )) ) {
		return NULL;
	}
	
	/* No algorithmic mapping, meaning that we have to figure out the
	   primary group SID according to group mapping and the user SID must
	   be a newly allocated one.  We rely on the user's Unix primary gid.
	   We have no choice but to fail if we can't find it. */

	if ( sampass->unix_pw ) {
		pwd = sampass->unix_pw;
	} else {
		pwd = Get_Pwnam_alloc( sampass, pdb_get_username(sampass) );
	}

	if ( !pwd ) {
		DEBUG(0,("pdb_get_group_sid: Failed to find Unix account for %s\n", pdb_get_username(sampass) ));
		return NULL;
	}
	
	if ( pdb_gid_to_sid(pwd->pw_gid, gsid) ) {
		enum lsa_SidType type = SID_NAME_UNKNOWN;
		TALLOC_CTX *mem_ctx = talloc_init("pdb_get_group_sid");
		bool lookup_ret;
		
		if (!mem_ctx) {
			return NULL;
		}

		/* Now check that it's actually a domain group and not something else */

		lookup_ret = lookup_sid(mem_ctx, gsid, NULL, NULL, &type);

		TALLOC_FREE( mem_ctx );

		if ( lookup_ret && (type == SID_NAME_DOM_GRP) ) {
			sampass->group_sid = gsid;
			return sampass->group_sid;
		}

		DEBUG(3, ("Primary group for user %s is a %s and not a domain group\n", 
			pwd->pw_name, sid_type_lookup(type)));
	}

	/* Just set it to the 'Domain Users' RID of 512 which will 
	   always resolve to a name */
		   
	sid_copy( gsid, get_global_sam_sid() );
	sid_append_rid( gsid, DOMAIN_GROUP_RID_USERS );
		
	sampass->group_sid = gsid;
		
	return sampass->group_sid;
}	
Пример #16
0
static NTSTATUS cmd_samr_query_useraliases(struct cli_state *cli, 
                                          TALLOC_CTX *mem_ctx,
                                          int argc, char **argv) 
{
	POLICY_HND 		connect_pol, domain_pol;
	NTSTATUS		result = NT_STATUS_UNSUCCESSFUL;
	uint32 			user_rid, num_aliases, *alias_rids;
	int 			i;
	fstring			server;
	DOM_SID			tmp_sid;
	DOM_SID2		sid;
	DOM_SID global_sid_Builtin;

	string_to_sid(&global_sid_Builtin, "S-1-5-32");

	if (argc != 3) {
		printf("Usage: %s builtin|domain rid\n", argv[0]);
		return NT_STATUS_OK;
	}

	sscanf(argv[2], "%i", &user_rid);

	slprintf (server, sizeof(fstring)-1, "\\\\%s", cli->desthost);
	strupper (server);
		
	result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
				  &connect_pol);
	if (!NT_STATUS_IS_OK(result)) {
		goto done;
	}

	if (StrCaseCmp(argv[1], "domain")==0)
		result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
					      MAXIMUM_ALLOWED_ACCESS,
					      &domain_sid, &domain_pol);
	else if (StrCaseCmp(argv[1], "builtin")==0)
		result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
					      MAXIMUM_ALLOWED_ACCESS,
					      &global_sid_Builtin, &domain_pol);
	else
		return NT_STATUS_OK;

	if (!NT_STATUS_IS_OK(result)) {
		goto done;
	}

	sid_copy(&tmp_sid, &domain_sid);
	sid_append_rid(&tmp_sid, user_rid);
	init_dom_sid2(&sid, &tmp_sid);

	result = cli_samr_query_useraliases(cli, mem_ctx, &domain_pol, 1, &sid, &num_aliases, &alias_rids);
	if (!NT_STATUS_IS_OK(result)) {
		goto done;
	}

	for (i = 0; i < num_aliases; i++) {
		printf("\tgroup rid:[0x%x]\n", alias_rids[i]);
	}

 done:
	return result;
}
Пример #17
0
static NTSTATUS auth_domain_admin_user_info_dc(TALLOC_CTX *mem_ctx,
					      const char *netbios_name,
					      const char *domain_name,
					      struct dom_sid *domain_sid,
					      struct auth_user_info_dc **_user_info_dc)
{
	struct auth_user_info_dc *user_info_dc;
	struct auth_user_info *info;

	user_info_dc = talloc(mem_ctx, struct auth_user_info_dc);
	NT_STATUS_HAVE_NO_MEMORY(user_info_dc);

	user_info_dc->num_sids = 7;
	user_info_dc->sids = talloc_array(user_info_dc, struct dom_sid, user_info_dc->num_sids);

	user_info_dc->sids[PRIMARY_USER_SID_INDEX] = *domain_sid;
	sid_append_rid(&user_info_dc->sids[PRIMARY_USER_SID_INDEX], DOMAIN_RID_ADMINISTRATOR);

	user_info_dc->sids[PRIMARY_GROUP_SID_INDEX] = *domain_sid;
	sid_append_rid(&user_info_dc->sids[PRIMARY_USER_SID_INDEX], DOMAIN_RID_USERS);

	user_info_dc->sids[2] = global_sid_Builtin_Administrators;

	user_info_dc->sids[3] = *domain_sid;
	sid_append_rid(&user_info_dc->sids[3], DOMAIN_RID_ADMINS);
	user_info_dc->sids[4] = *domain_sid;
	sid_append_rid(&user_info_dc->sids[4], DOMAIN_RID_ENTERPRISE_ADMINS);
	user_info_dc->sids[5] = *domain_sid;
	sid_append_rid(&user_info_dc->sids[5], DOMAIN_RID_POLICY_ADMINS);
	user_info_dc->sids[6] = *domain_sid;
	sid_append_rid(&user_info_dc->sids[6], DOMAIN_RID_SCHEMA_ADMINS);

	/* What should the session key be?*/
	user_info_dc->user_session_key = data_blob_talloc(user_info_dc, NULL, 16);
	NT_STATUS_HAVE_NO_MEMORY(user_info_dc->user_session_key.data);

	user_info_dc->lm_session_key = data_blob_talloc(user_info_dc, NULL, 16);
	NT_STATUS_HAVE_NO_MEMORY(user_info_dc->lm_session_key.data);

	data_blob_clear(&user_info_dc->user_session_key);
	data_blob_clear(&user_info_dc->lm_session_key);

	user_info_dc->info = info = talloc_zero(user_info_dc, struct auth_user_info);
	NT_STATUS_HAVE_NO_MEMORY(user_info_dc->info);

	info->account_name = talloc_strdup(info, "Administrator");
	NT_STATUS_HAVE_NO_MEMORY(info->account_name);

	info->domain_name = talloc_strdup(info, domain_name);
	NT_STATUS_HAVE_NO_MEMORY(info->domain_name);

	info->full_name = talloc_strdup(info, "Administrator");
	NT_STATUS_HAVE_NO_MEMORY(info->full_name);

	info->logon_script = talloc_strdup(info, "");
	NT_STATUS_HAVE_NO_MEMORY(info->logon_script);

	info->profile_path = talloc_strdup(info, "");
	NT_STATUS_HAVE_NO_MEMORY(info->profile_path);

	info->home_directory = talloc_strdup(info, "");
	NT_STATUS_HAVE_NO_MEMORY(info->home_directory);

	info->home_drive = talloc_strdup(info, "");
	NT_STATUS_HAVE_NO_MEMORY(info->home_drive);

	info->logon_server = talloc_strdup(info, netbios_name);
	NT_STATUS_HAVE_NO_MEMORY(info->logon_server);

	info->last_logon = 0;
	info->last_logoff = 0;
	info->acct_expiry = 0;
	info->last_password_change = 0;
	info->allow_password_change = 0;
	info->force_password_change
Пример #18
0
bool dom_sid_parse_endp(const char *sidstr,struct dom_sid *sidout,
			const char **endp)
{
	const char *p;
	char *q;
	/* BIG NOTE: this function only does SIDS where the identauth is not >= 2^32 */
	uint64_t conv;

	ZERO_STRUCTP(sidout);

	if ((sidstr[0] != 'S' && sidstr[0] != 's') || sidstr[1] != '-') {
		goto format_error;
	}

	/* Get the revision number. */
	p = sidstr + 2;

	if (!isdigit(*p)) {
		goto format_error;
	}

	conv = strtoul(p, &q, 10);
	if (!q || (*q != '-') || conv > UINT8_MAX) {
		goto format_error;
	}
	sidout->sid_rev_num = (uint8_t) conv;
	q++;

	if (!isdigit(*q)) {
		goto format_error;
	}

	/* get identauth */
	conv = strtoull(q, &q, 0);
	if (!q || conv & AUTHORITY_MASK) {
		goto format_error;
	}

	/* When identauth >= UINT32_MAX, it's in hex with a leading 0x */
	/* NOTE - the conv value is in big-endian format. */
	sidout->id_auth[0] = (conv & 0xff0000000000ULL) >> 40;
	sidout->id_auth[1] = (conv & 0x00ff00000000ULL) >> 32;
	sidout->id_auth[2] = (conv & 0x0000ff000000ULL) >> 24;
	sidout->id_auth[3] = (conv & 0x000000ff0000ULL) >> 16;
	sidout->id_auth[4] = (conv & 0x00000000ff00ULL) >> 8;
	sidout->id_auth[5] = (conv & 0x0000000000ffULL);

	sidout->num_auths = 0;
	if (*q != '-') {
		/* Just id_auth, no subauths */
		goto done;
	}

	q++;

	while (true) {
		char *end;

		if (!isdigit(*q)) {
			goto format_error;
		}

		conv = strtoull(q, &end, 10);
		if (end == q || conv > UINT32_MAX) {
			goto format_error;
		}

		if (!sid_append_rid(sidout, conv)) {
			DEBUG(3, ("Too many sid auths in %s\n", sidstr));
			return false;
		}

		q = end;
		if (*q != '-') {
			break;
		}
		q += 1;
	}
done:
	if (endp != NULL) {
		*endp = q;
	}
	return true;

format_error:
	DEBUG(3, ("string_to_sid: SID %s is not in a valid format\n", sidstr));
	return false;
}
Пример #19
0
_PUBLIC_ NTSTATUS authsam_make_user_info_dc(TALLOC_CTX *mem_ctx,
					   struct ldb_context *sam_ctx,
					   const char *netbios_name,
					   const char *domain_name,
					   struct ldb_dn *domain_dn, 
					   struct ldb_message *msg,
					   DATA_BLOB user_sess_key,
					   DATA_BLOB lm_sess_key,
					   struct auth_user_info_dc **_user_info_dc)
{
	NTSTATUS status;
	struct auth_user_info_dc *user_info_dc;
	struct auth_user_info *info;
	const char *str, *filter;
	/* SIDs for the account and his primary group */
	struct dom_sid *account_sid;
	const char *primary_group_string;
	const char *primary_group_dn;
	DATA_BLOB primary_group_blob;
	/* SID structures for the expanded group memberships */
	struct dom_sid *sids = NULL;
	unsigned int num_sids = 0, i;
	struct dom_sid *domain_sid;
	TALLOC_CTX *tmp_ctx;
	struct ldb_message_element *el;

	user_info_dc = talloc(mem_ctx, struct auth_user_info_dc);
	NT_STATUS_HAVE_NO_MEMORY(user_info_dc);

	tmp_ctx = talloc_new(user_info_dc);
	NT_STATUS_HAVE_NO_MEMORY_AND_FREE(user_info_dc, user_info_dc);

	sids = talloc_array(user_info_dc, struct dom_sid, 2);
	NT_STATUS_HAVE_NO_MEMORY_AND_FREE(sids, user_info_dc);

	num_sids = 2;

	account_sid = samdb_result_dom_sid(user_info_dc, msg, "objectSid");
	NT_STATUS_HAVE_NO_MEMORY_AND_FREE(account_sid, user_info_dc);

	status = dom_sid_split_rid(tmp_ctx, account_sid, &domain_sid, NULL);
	if (!NT_STATUS_IS_OK(status)) {
		talloc_free(user_info_dc);
		return status;
	}

	sids[PRIMARY_USER_SID_INDEX] = *account_sid;
	sids[PRIMARY_GROUP_SID_INDEX] = *domain_sid;
	sid_append_rid(&sids[PRIMARY_GROUP_SID_INDEX], ldb_msg_find_attr_as_uint(msg, "primaryGroupID", ~0));

	/* Filter out builtin groups from this token.  We will search
	 * for builtin groups later, and not include them in the PAC
	 * on SamLogon validation info */
	filter = talloc_asprintf(tmp_ctx, "(&(objectClass=group)(!(groupType:1.2.840.113556.1.4.803:=%u))(groupType:1.2.840.113556.1.4.803:=%u))", GROUP_TYPE_BUILTIN_LOCAL_GROUP, GROUP_TYPE_SECURITY_ENABLED);
	NT_STATUS_HAVE_NO_MEMORY_AND_FREE(filter, user_info_dc);

	primary_group_string = dom_sid_string(tmp_ctx, &sids[PRIMARY_GROUP_SID_INDEX]);
	NT_STATUS_HAVE_NO_MEMORY_AND_FREE(primary_group_string, user_info_dc);

	primary_group_dn = talloc_asprintf(tmp_ctx, "<SID=%s>", primary_group_string);
	NT_STATUS_HAVE_NO_MEMORY_AND_FREE(primary_group_dn, user_info_dc);

	primary_group_blob = data_blob_string_const(primary_group_dn);

	/* Expands the primary group - this function takes in
	 * memberOf-like values, so we fake one up with the
	 * <SID=S-...> format of DN and then let it expand
	 * them, as long as they meet the filter - so only
	 * domain groups, not builtin groups
	 *
	 * The primary group is still treated specially, so we set the
	 * 'only childs' flag to true
	 */
	status = dsdb_expand_nested_groups(sam_ctx, &primary_group_blob, true, filter,
					   user_info_dc, &sids, &num_sids);
	if (!NT_STATUS_IS_OK(status)) {
		talloc_free(user_info_dc);
		return status;
	}

	/* Expands the additional groups */
	el = ldb_msg_find_element(msg, "memberOf");
	for (i = 0; el && i < el->num_values; i++) {
		/* This function takes in memberOf values and expands
		 * them, as long as they meet the filter - so only
		 * domain groups, not builtin groups */
		status = dsdb_expand_nested_groups(sam_ctx, &el->values[i], false, filter,
						   user_info_dc, &sids, &num_sids);
		if (!NT_STATUS_IS_OK(status)) {
			talloc_free(user_info_dc);
			return status;
		}
	}

	user_info_dc->sids = sids;
	user_info_dc->num_sids = num_sids;

	user_info_dc->info = info = talloc_zero(user_info_dc, struct auth_user_info);
	NT_STATUS_HAVE_NO_MEMORY(user_info_dc->info);

	info->account_name = talloc_steal(info,
		ldb_msg_find_attr_as_string(msg, "sAMAccountName", NULL));

	info->domain_name = talloc_strdup(info, domain_name);
	NT_STATUS_HAVE_NO_MEMORY_AND_FREE(info->domain_name,
		user_info_dc);

	str = ldb_msg_find_attr_as_string(msg, "displayName", "");
	info->full_name = talloc_strdup(info, str);
	NT_STATUS_HAVE_NO_MEMORY_AND_FREE(info->full_name, user_info_dc);

	str = ldb_msg_find_attr_as_string(msg, "scriptPath", "");
	info->logon_script = talloc_strdup(info, str);
	NT_STATUS_HAVE_NO_MEMORY_AND_FREE(info->logon_script,
		user_info_dc);

	str = ldb_msg_find_attr_as_string(msg, "profilePath", "");
	info->profile_path = talloc_strdup(info, str);
	NT_STATUS_HAVE_NO_MEMORY_AND_FREE(info->profile_path,
		user_info_dc);

	str = ldb_msg_find_attr_as_string(msg, "homeDirectory", "");
	info->home_directory = talloc_strdup(info, str);
	NT_STATUS_HAVE_NO_MEMORY_AND_FREE(info->home_directory,
		user_info_dc);

	str = ldb_msg_find_attr_as_string(msg, "homeDrive", "");
	info->home_drive = talloc_strdup(info, str);
	NT_STATUS_HAVE_NO_MEMORY_AND_FREE(info->home_drive, user_info_dc);

	info->logon_server = talloc_strdup(info, netbios_name);
	NT_STATUS_HAVE_NO_MEMORY_AND_FREE(info->logon_server,
		user_info_dc);

	info->last_logon = samdb_result_nttime(msg, "lastLogon", 0);
	info->last_logoff = samdb_result_last_logoff(msg);
	info->acct_expiry = samdb_result_account_expires(msg);
	info->last_password_change = samdb_result_nttime(msg,
		"pwdLastSet", 0);
	info->allow_password_change
		= samdb_result_allow_password_change(sam_ctx, mem_ctx, 
			domain_dn, msg, "pwdLastSet");
	info->force_password_change
		= samdb_result_force_password_change(sam_ctx, mem_ctx,
			domain_dn, msg);
	info->logon_count = ldb_msg_find_attr_as_uint(msg, "logonCount", 0);
	info->bad_password_count = ldb_msg_find_attr_as_uint(msg, "badPwdCount",
		0);

	info->acct_flags = samdb_result_acct_flags(sam_ctx, mem_ctx,
							  msg, domain_dn);

	user_info_dc->user_session_key = data_blob_talloc(user_info_dc,
							 user_sess_key.data,
							 user_sess_key.length);
	if (user_sess_key.data) {
		NT_STATUS_HAVE_NO_MEMORY_AND_FREE(user_info_dc->user_session_key.data,
						  user_info_dc);
	}
	user_info_dc->lm_session_key = data_blob_talloc(user_info_dc,
						       lm_sess_key.data,
						       lm_sess_key.length);
	if (lm_sess_key.data) {
		NT_STATUS_HAVE_NO_MEMORY_AND_FREE(user_info_dc->lm_session_key.data,
						  user_info_dc);
	}

	if (info->acct_flags & ACB_SVRTRUST) {
		/* the SID_NT_ENTERPRISE_DCS SID gets added into the
		   PAC */
		user_info_dc->sids = talloc_realloc(user_info_dc,
						   user_info_dc->sids,
						   struct dom_sid,
						   user_info_dc->num_sids+1);
		NT_STATUS_HAVE_NO_MEMORY_AND_FREE(user_info_dc->sids, user_info_dc);
		user_info_dc->sids[user_info_dc->num_sids] = global_sid_Enterprise_DCs;
		user_info_dc->num_sids++;
	}
Пример #20
0
enum winbindd_result winbindd_dual_getsidaliases(struct winbindd_domain *domain,
						 struct winbindd_cli_state *state)
{
	DOM_SID *sids = NULL;
	size_t num_sids = 0;
	char *sidstr = NULL;
	ssize_t len;
	size_t i;
	uint32 num_aliases;
	uint32 *alias_rids;
	NTSTATUS result;

	DEBUG(3, ("[%5lu]: getsidaliases\n", (unsigned long)state->pid));

	sidstr = state->request->extra_data.data;
	if (sidstr == NULL) {
		sidstr = talloc_strdup(state->mem_ctx, "\n"); /* No SID */
		if (!sidstr) {
			DEBUG(0, ("Out of memory\n"));
			return WINBINDD_ERROR;
		}
	}

	DEBUG(10, ("Sidlist: %s\n", sidstr));

	if (!parse_sidlist(state->mem_ctx, sidstr, &sids, &num_sids)) {
		DEBUG(0, ("Could not parse SID list: %s\n", sidstr));
		return WINBINDD_ERROR;
	}

	num_aliases = 0;
	alias_rids = NULL;

	result = domain->methods->lookup_useraliases(domain,
						     state->mem_ctx,
						     num_sids, sids,
						     &num_aliases,
						     &alias_rids);

	if (!NT_STATUS_IS_OK(result)) {
		DEBUG(3, ("Could not lookup_useraliases: %s\n",
			  nt_errstr(result)));
		return WINBINDD_ERROR;
	}

	num_sids = 0;
	sids = NULL;
	sidstr = NULL;

	DEBUG(10, ("Got %d aliases\n", num_aliases));

	for (i=0; i<num_aliases; i++) {
		DOM_SID sid;
		DEBUGADD(10, (" rid %d\n", alias_rids[i]));
		sid_copy(&sid, &domain->sid);
		sid_append_rid(&sid, alias_rids[i]);
		result = add_sid_to_array(state->mem_ctx, &sid, &sids,
					  &num_sids);
		if (!NT_STATUS_IS_OK(result)) {
			return WINBINDD_ERROR;
		}
	}


	if (!print_sidlist(state->mem_ctx, sids, num_sids, &sidstr, &len)) {
		DEBUG(0, ("Could not print_sidlist\n"));
		state->response->extra_data.data = NULL;
		return WINBINDD_ERROR;
	}

	state->response->extra_data.data = NULL;

	if (sidstr) {
		state->response->extra_data.data = sidstr;
		DEBUG(10, ("aliases_list: %s\n",
			   (char *)state->response->extra_data.data));
		state->response->length += len+1;
		state->response->data.num_entries = num_sids;
	}

	return WINBINDD_OK;
}
Пример #21
0
/* Lookup groups a user is a member of. */
static NTSTATUS lookup_usergroups(struct winbindd_domain *domain,
				  TALLOC_CTX *mem_ctx,
				  const DOM_SID *sid, 
				  uint32 *p_num_groups, DOM_SID **user_sids)
{
	ADS_STRUCT *ads = NULL;
	const char *attrs[] = {"tokenGroups", "primaryGroupID", NULL};
	ADS_STATUS rc;
	int count;
	LDAPMessage *msg = NULL;
	char *user_dn = NULL;
	DOM_SID *sids;
	int i;
	DOM_SID primary_group;
	uint32 primary_group_rid;
	NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
	size_t num_groups = 0;

	DEBUG(3,("ads: lookup_usergroups\n"));
	*p_num_groups = 0;

	status = lookup_usergroups_cached(domain, mem_ctx, sid, 
					  p_num_groups, user_sids);
	if (NT_STATUS_IS_OK(status)) {
		return NT_STATUS_OK;
	}

	if ( !winbindd_can_contact_domain( domain ) ) {
		DEBUG(10,("lookup_usergroups: No incoming trust for domain %s\n",
			  domain->name));

		/* Tell the cache manager not to remember this one */

		return NT_STATUS_SYNCHRONIZATION_REQUIRED;
	}

	ads = ads_cached_connection(domain);

	if (!ads) {
		domain->last_status = NT_STATUS_SERVER_DISABLED;
		status = NT_STATUS_SERVER_DISABLED;
		goto done;
	}

	rc = ads_search_retry_sid(ads, &msg, sid, attrs);

	if (!ADS_ERR_OK(rc)) {
		status = ads_ntstatus(rc);
		DEBUG(1, ("lookup_usergroups(sid=%s) ads_search tokenGroups: "
			  "%s\n", sid_string_dbg(sid), ads_errstr(rc)));
		goto done;
	}

	count = ads_count_replies(ads, msg);
	if (count != 1) {
		status = NT_STATUS_UNSUCCESSFUL;
		DEBUG(1,("lookup_usergroups(sid=%s) ads_search tokenGroups: "
			 "invalid number of results (count=%d)\n", 
			 sid_string_dbg(sid), count));
		goto done;
	}

	if (!msg) {
		DEBUG(1,("lookup_usergroups(sid=%s) ads_search tokenGroups: NULL msg\n", 
			 sid_string_dbg(sid)));
		status = NT_STATUS_UNSUCCESSFUL;
		goto done;
	}

	user_dn = ads_get_dn(ads, mem_ctx, msg);
	if (user_dn == NULL) {
		status = NT_STATUS_NO_MEMORY;
		goto done;
	}

	if (!ads_pull_uint32(ads, msg, "primaryGroupID", &primary_group_rid)) {
		DEBUG(1,("%s: No primary group for sid=%s !?\n", 
			 domain->name, sid_string_dbg(sid)));
		goto done;
	}

	sid_copy(&primary_group, &domain->sid);
	sid_append_rid(&primary_group, primary_group_rid);

	count = ads_pull_sids(ads, mem_ctx, msg, "tokenGroups", &sids);

	/* there must always be at least one group in the token, 
	   unless we are talking to a buggy Win2k server */

	/* actually this only happens when the machine account has no read
	 * permissions on the tokenGroup attribute - gd */

	if (count == 0) {

		/* no tokenGroups */

		/* lookup what groups this user is a member of by DN search on
		 * "memberOf" */

		status = lookup_usergroups_memberof(domain, mem_ctx, user_dn,
						    &primary_group,
						    &num_groups, user_sids);
		*p_num_groups = (uint32)num_groups;
		if (NT_STATUS_IS_OK(status)) {
			goto done;
		}

		/* lookup what groups this user is a member of by DN search on
		 * "member" */

		status = lookup_usergroups_member(domain, mem_ctx, user_dn, 
						  &primary_group,
						  &num_groups, user_sids);
		*p_num_groups = (uint32)num_groups;
		goto done;
	}

	*user_sids = NULL;
	num_groups = 0;

	status = add_sid_to_array(mem_ctx, &primary_group, user_sids,
				  &num_groups);
	if (!NT_STATUS_IS_OK(status)) {
		goto done;
	}

	for (i=0;i<count;i++) {

		/* ignore Builtin groups from ADS - Guenther */
		if (sid_check_is_in_builtin(&sids[i])) {
			continue;
		}

		status = add_sid_to_array_unique(mem_ctx, &sids[i],
						 user_sids, &num_groups);
		if (!NT_STATUS_IS_OK(status)) {
			goto done;
		}
	}

	*p_num_groups = (uint32)num_groups;
	status = (*user_sids != NULL) ? NT_STATUS_OK : NT_STATUS_NO_MEMORY;

	DEBUG(3,("ads lookup_usergroups (tokenGroups) succeeded for sid=%s\n",
		 sid_string_dbg(sid)));
done:
	TALLOC_FREE(user_dn);
	ads_msgfree(ads, msg);
	return status;
}
Пример #22
0
/*****************************************************************************
 For idmap conversion: convert one record to new format
 Ancient versions (eg 2.2.3a) of winbindd_idmap.tdb mapped DOMAINNAME/rid
 instead of the SID.
*****************************************************************************/
static int convert_fn(struct db_record *rec, void *private_data)
{
	struct winbindd_domain *domain;
	char *p;
	NTSTATUS status;
	DOM_SID sid;
	uint32 rid;
	fstring keystr;
	fstring dom_name;
	TDB_DATA key2;
	struct convert_fn_state *s = (struct convert_fn_state *)private_data;

	DEBUG(10,("Converting %s\n", (const char *)rec->key.dptr));

	p = strchr((const char *)rec->key.dptr, '/');
	if (!p)
		return 0;

	*p = 0;
	fstrcpy(dom_name, (const char *)rec->key.dptr);
	*p++ = '/';

	domain = find_domain_from_name(dom_name);
	if (domain == NULL) {
		/* We must delete the old record. */
		DEBUG(0,("Unable to find domain %s\n", dom_name ));
		DEBUG(0,("deleting record %s\n", (const char *)rec->key.dptr ));

		status = rec->delete_rec(rec);
		if (!NT_STATUS_IS_OK(status)) {
			DEBUG(0, ("Unable to delete record %s:%s\n",
				(const char *)rec->key.dptr,
				nt_errstr(status)));
			s->failed = true;
			return -1;
		}

		return 0;
	}

	rid = atoi(p);

	sid_copy(&sid, &domain->sid);
	sid_append_rid(&sid, rid);

	sid_to_fstring(keystr, &sid);
	key2 = string_term_tdb_data(keystr);

	status = dbwrap_store(s->db, key2, rec->value, TDB_INSERT);
	if (!NT_STATUS_IS_OK(status)) {
		DEBUG(0,("Unable to add record %s:%s\n",
			(const char *)key2.dptr,
			nt_errstr(status)));
		s->failed = true;
		return -1;
	}

	status = dbwrap_store(s->db, rec->value, key2, TDB_REPLACE);
	if (!NT_STATUS_IS_OK(status)) {
		DEBUG(0,("Unable to update record %s:%s\n",
			(const char *)rec->value.dptr,
			nt_errstr(status)));
		s->failed = true;
		return -1;
	}

	status = rec->delete_rec(rec);
	if (!NT_STATUS_IS_OK(status)) {
		DEBUG(0,("Unable to delete record %s:%s\n",
			(const char *)rec->key.dptr,
			nt_errstr(status)));
		s->failed = true;
		return -1;
	}

	return 0;
}
Пример #23
0
BOOL string_to_sid(DOM_SID *sidout, const char *sidstr)
{
	pstring tok;
	char *q;
	const char *p;
	/* BIG NOTE: this function only does SIDS where the identauth is not >= 2^32 */
	uint32 ia;
  
	if (StrnCaseCmp( sidstr, "S-", 2)) {
		DEBUG(0,("string_to_sid: Sid %s does not start with 'S-'.\n", sidstr));
		return False;
	}

	memset((char *)sidout, '\0', sizeof(DOM_SID));

	p = q = SMB_STRDUP(sidstr + 2);
	if (p == NULL) {
		DEBUG(0, ("string_to_sid: out of memory!\n"));
		return False;
	}

	if (!next_token(&p, tok, "-", sizeof(tok))) {
		DEBUG(0,("string_to_sid: Sid %s is not in a valid format.\n", sidstr));
		SAFE_FREE(q);
		return False;
	}

	/* Get the revision number. */
	sidout->sid_rev_num = (uint8)strtoul(tok, NULL, 10);

	if (!next_token(&p, tok, "-", sizeof(tok))) {
		DEBUG(0,("string_to_sid: Sid %s is not in a valid format.\n", sidstr));
		SAFE_FREE(q);
		return False;
	}

	/* identauth in decimal should be <  2^32 */
	ia = (uint32)strtoul(tok, NULL, 10);

	/* NOTE - the ia value is in big-endian format. */
	sidout->id_auth[0] = 0;
	sidout->id_auth[1] = 0;
	sidout->id_auth[2] = (ia & 0xff000000) >> 24;
	sidout->id_auth[3] = (ia & 0x00ff0000) >> 16;
	sidout->id_auth[4] = (ia & 0x0000ff00) >> 8;
	sidout->id_auth[5] = (ia & 0x000000ff);

	sidout->num_auths = 0;

	while(next_token(&p, tok, "-", sizeof(tok)) && 
		sidout->num_auths < MAXSUBAUTHS) {
		/* 
		 * NOTE - the subauths are in native machine-endian format. They
		 * are converted to little-endian when linearized onto the wire.
		 */
		sid_append_rid(sidout, (uint32)strtoul(tok, NULL, 10));
	}

	SAFE_FREE(q);
	return True;
}
Пример #24
0
bool lookup_name(TALLOC_CTX *mem_ctx,
		 const char *full_name, int flags,
		 const char **ret_domain, const char **ret_name,
		 DOM_SID *ret_sid, enum lsa_SidType *ret_type)
{
	char *p;
	const char *tmp;
	const char *domain = NULL;
	const char *name = NULL;
	uint32 rid;
	DOM_SID sid;
	enum lsa_SidType type;
	TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);

	if (tmp_ctx == NULL) {
		DEBUG(0, ("talloc_new failed\n"));
		return false;
	}

	p = strchr_m(full_name, '\\');

	if (p != NULL) {
		domain = talloc_strndup(tmp_ctx, full_name,
					PTR_DIFF(p, full_name));
		name = talloc_strdup(tmp_ctx, p+1);
	} else {
		domain = talloc_strdup(tmp_ctx, "");
		name = talloc_strdup(tmp_ctx, full_name);
	}

	if ((domain == NULL) || (name == NULL)) {
		DEBUG(0, ("talloc failed\n"));
		TALLOC_FREE(tmp_ctx);
		return false;
	}

	DEBUG(10,("lookup_name: %s => %s (domain), %s (name)\n",
		full_name, domain, name));
	DEBUG(10, ("lookup_name: flags = 0x0%x\n", flags));

	if ((flags & LOOKUP_NAME_DOMAIN) &&
	    strequal(domain, get_global_sam_name()))
	{

		/* It's our own domain, lookup the name in passdb */
		if (lookup_global_sam_name(name, flags, &rid, &type)) {
			sid_copy(&sid, get_global_sam_sid());
			sid_append_rid(&sid, rid);
			goto ok;
		}
		TALLOC_FREE(tmp_ctx);
		return false;
	}

	if ((flags & LOOKUP_NAME_BUILTIN) &&
	    strequal(domain, builtin_domain_name()))
	{
		/* Explicit request for a name in BUILTIN */
		if (lookup_builtin_name(name, &rid)) {
			sid_copy(&sid, &global_sid_Builtin);
			sid_append_rid(&sid, rid);
			type = SID_NAME_ALIAS;
			goto ok;
		}
		TALLOC_FREE(tmp_ctx);
		return false;
	}

	/* Try the explicit winbind lookup first, don't let it guess the
	 * domain yet at this point yet. This comes later. */

	if ((domain[0] != '\0') &&
	    (flags & ~(LOOKUP_NAME_DOMAIN|LOOKUP_NAME_ISOLATED)) &&
	    (winbind_lookup_name(domain, name, &sid, &type))) {
			goto ok;
	}

	if (!(flags & LOOKUP_NAME_EXPLICIT) && strequal(domain, unix_users_domain_name())) {
		if (lookup_unix_user_name(name, &sid)) {
			type = SID_NAME_USER;
			goto ok;
		}
		TALLOC_FREE(tmp_ctx);
		return false;
	}

	if (!(flags & LOOKUP_NAME_EXPLICIT) && strequal(domain, unix_groups_domain_name())) {
		if (lookup_unix_group_name(name, &sid)) {
			type = SID_NAME_DOM_GRP;
			goto ok;
		}
		TALLOC_FREE(tmp_ctx);
		return false;
	}

	if ((domain[0] == '\0') && (!(flags & LOOKUP_NAME_ISOLATED))) {
		TALLOC_FREE(tmp_ctx);
		return false;
	}

	/* Now the guesswork begins, we haven't been given an explicit
	 * domain. Try the sequence as documented on
	 * http://msdn.microsoft.com/library/en-us/secmgmt/security/lsalookupnames.asp
	 * November 27, 2005 */

	/* 1. well-known names */

	if ((flags & LOOKUP_NAME_WKN) &&
	    lookup_wellknown_name(tmp_ctx, name, &sid, &domain))
	{
		type = SID_NAME_WKN_GRP;
		goto ok;
	}

	/* 2. Builtin domain as such */

	if ((flags & (LOOKUP_NAME_BUILTIN|LOOKUP_NAME_REMOTE)) &&
	    strequal(name, builtin_domain_name()))
	{
		/* Swap domain and name */
		tmp = name; name = domain; domain = tmp;
		sid_copy(&sid, &global_sid_Builtin);
		type = SID_NAME_DOMAIN;
		goto ok;
	}

	/* 3. Account domain */

	if ((flags & LOOKUP_NAME_DOMAIN) &&
	    strequal(name, get_global_sam_name()))
	{
		if (!secrets_fetch_domain_sid(name, &sid)) {
			DEBUG(3, ("Could not fetch my SID\n"));
			TALLOC_FREE(tmp_ctx);
			return false;
		}
		/* Swap domain and name */
		tmp = name; name = domain; domain = tmp;
		type = SID_NAME_DOMAIN;
		goto ok;
	}

	/* 4. Primary domain */

	if ((flags & LOOKUP_NAME_DOMAIN) && !IS_DC &&
	    strequal(name, lp_workgroup()))
	{
		if (!secrets_fetch_domain_sid(name, &sid)) {
			DEBUG(3, ("Could not fetch the domain SID\n"));
			TALLOC_FREE(tmp_ctx);
			return false;
		}
		/* Swap domain and name */
		tmp = name; name = domain; domain = tmp;
		type = SID_NAME_DOMAIN;
		goto ok;
	}

	/* 5. Trusted domains as such, to me it looks as if members don't do
              this, tested an XP workstation in a NT domain -- vl */

	if ((flags & LOOKUP_NAME_REMOTE) && IS_DC &&
	    (pdb_get_trusteddom_pw(name, NULL, &sid, NULL)))
	{
		/* Swap domain and name */
		tmp = name; name = domain; domain = tmp;
		type = SID_NAME_DOMAIN;
		goto ok;
	}

	/* 6. Builtin aliases */	

	if ((flags & LOOKUP_NAME_BUILTIN) &&
	    lookup_builtin_name(name, &rid))
	{
		domain = talloc_strdup(tmp_ctx, builtin_domain_name());
		sid_copy(&sid, &global_sid_Builtin);
		sid_append_rid(&sid, rid);
		type = SID_NAME_ALIAS;
		goto ok;
	}

	/* 7. Local systems' SAM (DCs don't have a local SAM) */
	/* 8. Primary SAM (On members, this is the domain) */

	/* Both cases are done by looking at our passdb */

	if ((flags & LOOKUP_NAME_DOMAIN) &&
	    lookup_global_sam_name(name, flags, &rid, &type))
	{
		domain = talloc_strdup(tmp_ctx, get_global_sam_name());
		sid_copy(&sid, get_global_sam_sid());
		sid_append_rid(&sid, rid);
		goto ok;
	}

	/* Now our local possibilities are exhausted. */

	if (!(flags & LOOKUP_NAME_REMOTE)) {
		TALLOC_FREE(tmp_ctx);
		return false;
	}

	/* If we are not a DC, we have to ask in our primary domain. Let
	 * winbind do that. */

	if (!IS_DC &&
	    (winbind_lookup_name(lp_workgroup(), name, &sid, &type))) {
		domain = talloc_strdup(tmp_ctx, lp_workgroup());
		goto ok;
	}

	/* 9. Trusted domains */

	/* If we're a DC we have to ask all trusted DC's. Winbind does not do
	 * that (yet), but give it a chance. */

	if (IS_DC && winbind_lookup_name("", name, &sid, &type)) {
		DOM_SID dom_sid;
		uint32 tmp_rid;
		enum lsa_SidType domain_type;
		
		if (type == SID_NAME_DOMAIN) {
			/* Swap name and type */
			tmp = name; name = domain; domain = tmp;
			goto ok;
		}

		/* Here we have to cope with a little deficiency in the
		 * winbind API: We have to ask it again for the name of the
		 * domain it figured out itself. Maybe fix that later... */

		sid_copy(&dom_sid, &sid);
		sid_split_rid(&dom_sid, &tmp_rid);

		if (!winbind_lookup_sid(tmp_ctx, &dom_sid, &domain, NULL,
					&domain_type) ||
		    (domain_type != SID_NAME_DOMAIN)) {
			DEBUG(2, ("winbind could not find the domain's name "
				  "it just looked up for us\n"));
			TALLOC_FREE(tmp_ctx);
			return false;
		}
		goto ok;
	}

	/* 10. Don't translate */

	/* 11. Ok, windows would end here. Samba has two more options:
               Unmapped users and unmapped groups */

	if (!(flags & LOOKUP_NAME_EXPLICIT) && lookup_unix_user_name(name, &sid)) {
		domain = talloc_strdup(tmp_ctx, unix_users_domain_name());
		type = SID_NAME_USER;
		goto ok;
	}

	if (!(flags & LOOKUP_NAME_EXPLICIT) && lookup_unix_group_name(name, &sid)) {
		domain = talloc_strdup(tmp_ctx, unix_groups_domain_name());
		type = SID_NAME_DOM_GRP;
		goto ok;
	}

	/*
	 * Ok, all possibilities tried. Fail.
	 */

	TALLOC_FREE(tmp_ctx);
	return false;

 ok:
	if ((domain == NULL) || (name == NULL)) {
		DEBUG(0, ("talloc failed\n"));
		TALLOC_FREE(tmp_ctx);
		return false;
	}

	/*
	 * Hand over the results to the talloc context we've been given.
	 */

	if ((ret_name != NULL) &&
	    !(*ret_name = talloc_strdup(mem_ctx, name))) {
		DEBUG(0, ("talloc failed\n"));
		TALLOC_FREE(tmp_ctx);
		return false;
	}

	if (ret_domain != NULL) {
		char *tmp_dom;
		if (!(tmp_dom = talloc_strdup(mem_ctx, domain))) {
			DEBUG(0, ("talloc failed\n"));
			TALLOC_FREE(tmp_ctx);
			return false;
		}
		strupper_m(tmp_dom);
		*ret_domain = tmp_dom;
	}

	if (ret_sid != NULL) {
		sid_copy(ret_sid, &sid);
	}

	if (ret_type != NULL) {
		*ret_type = type;
	}

	TALLOC_FREE(tmp_ctx);
	return true;
}
Пример #25
0
WERROR spoolss_create_default_secdesc(TALLOC_CTX *mem_ctx,
				      struct spoolss_security_descriptor **secdesc)
{
	struct security_ace ace[7];	/* max number of ace entries */
	int i = 0;
	uint32_t sa;
	struct security_acl *psa = NULL;
	struct security_descriptor *psd = NULL;
	struct dom_sid adm_sid;
	size_t sd_size;

	/* Create an ACE where Everyone is allowed to print */

	sa = PRINTER_ACE_PRINT;
	init_sec_ace(&ace[i++], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED,
		     sa, SEC_ACE_FLAG_CONTAINER_INHERIT);

	/* Add the domain admins group if we are a DC */

	if ( IS_DC ) {
		struct dom_sid domadmins_sid;

		sid_compose(&domadmins_sid, get_global_sam_sid(),
			    DOMAIN_RID_ADMINS);

		sa = PRINTER_ACE_FULL_CONTROL;
		init_sec_ace(&ace[i++], &domadmins_sid,
			SEC_ACE_TYPE_ACCESS_ALLOWED, sa,
			SEC_ACE_FLAG_OBJECT_INHERIT | SEC_ACE_FLAG_INHERIT_ONLY);
		init_sec_ace(&ace[i++], &domadmins_sid, SEC_ACE_TYPE_ACCESS_ALLOWED,
			sa, SEC_ACE_FLAG_CONTAINER_INHERIT);
	}
	else if (secrets_fetch_domain_sid(lp_workgroup(), &adm_sid)) {
		sid_append_rid(&adm_sid, DOMAIN_RID_ADMINISTRATOR);

		sa = PRINTER_ACE_FULL_CONTROL;
		init_sec_ace(&ace[i++], &adm_sid,
			SEC_ACE_TYPE_ACCESS_ALLOWED, sa,
			SEC_ACE_FLAG_OBJECT_INHERIT | SEC_ACE_FLAG_INHERIT_ONLY);
		init_sec_ace(&ace[i++], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED,
			sa, SEC_ACE_FLAG_CONTAINER_INHERIT);
	}

	/* add BUILTIN\Administrators as FULL CONTROL */

	sa = PRINTER_ACE_FULL_CONTROL;
	init_sec_ace(&ace[i++], &global_sid_Builtin_Administrators,
		SEC_ACE_TYPE_ACCESS_ALLOWED, sa,
		SEC_ACE_FLAG_OBJECT_INHERIT | SEC_ACE_FLAG_INHERIT_ONLY);
	init_sec_ace(&ace[i++], &global_sid_Builtin_Administrators,
		SEC_ACE_TYPE_ACCESS_ALLOWED,
		sa, SEC_ACE_FLAG_CONTAINER_INHERIT);

	/* add BUILTIN\Print Operators as FULL CONTROL */

	sa = PRINTER_ACE_FULL_CONTROL;
	init_sec_ace(&ace[i++], &global_sid_Builtin_Print_Operators,
		SEC_ACE_TYPE_ACCESS_ALLOWED, sa,
		SEC_ACE_FLAG_OBJECT_INHERIT | SEC_ACE_FLAG_INHERIT_ONLY);
	init_sec_ace(&ace[i++], &global_sid_Builtin_Print_Operators,
		SEC_ACE_TYPE_ACCESS_ALLOWED,
		sa, SEC_ACE_FLAG_CONTAINER_INHERIT);

	/* Make the security descriptor owned by the BUILTIN\Administrators */

	/* The ACL revision number in rpc_secdesc.h differs from the one
	   created by NT when setting ACE entries in printer
	   descriptors.  NT4 complains about the property being edited by a
	   NT5 machine. */

	if ((psa = make_sec_acl(mem_ctx, NT4_ACL_REVISION, i, ace)) != NULL) {
		psd = make_sec_desc(mem_ctx,
				    SD_REVISION,
				    SEC_DESC_SELF_RELATIVE,
				    &global_sid_Builtin_Administrators,
				    &global_sid_Builtin_Administrators,
				    NULL,
				    psa,
				    &sd_size);
	}

	if (psd == NULL) {
		DEBUG(0,("construct_default_printer_sd: Failed to make SEC_DESC.\n"));
		return WERR_NOMEM;
	}

	DEBUG(4,("construct_default_printer_sdb: size = %u.\n",
		 (unsigned int)sd_size));

	*secdesc = psd;

	return WERR_OK;
}