Пример #1
0
/*********************************************************
 Figure out if the input was an NT group or a SID string.
 Return the SID.
**********************************************************/
static bool get_sid_from_input(DOM_SID *sid, char *input)
{
	GROUP_MAP map;

	if (StrnCaseCmp( input, "S-", 2)) {
		/* Perhaps its the NT group name? */
		if (!pdb_getgrnam(&map, input)) {
			printf(_("NT Group %s doesn't exist in mapping DB\n"),
			       input);
			return false;
		} else {
			*sid = map.sid;
		}
	} else {
		if (!string_to_sid(sid, input)) {
			printf(_("converting sid %s from a string failed!\n"),
			       input);
			return false;
		}
	}
	return true;
}
static bool dbrec2map(const struct db_record *rec, GROUP_MAP *map)
{
	TDB_DATA key = dbwrap_record_get_key(rec);
	TDB_DATA value = dbwrap_record_get_value(rec);
	int ret = 0;
	fstring nt_name;
	fstring comment;

	if ((key.dsize < strlen(GROUP_PREFIX))
	    || (strncmp((char *)key.dptr, GROUP_PREFIX,
			GROUP_PREFIX_LEN) != 0)) {
		return False;
	}

	if (!string_to_sid(&map->sid, (const char *)key.dptr
			   + GROUP_PREFIX_LEN)) {
		return False;
	}

	ret = tdb_unpack(value.dptr, value.dsize, "ddff",
			  &map->gid, &map->sid_name_use,
			  &nt_name, &comment);

	if (ret == -1) {
		DEBUG(3, ("dbrec2map: tdb_unpack failure\n"));
		return false;
	}

	map->nt_name = talloc_strdup(map, nt_name);
	if (!map->nt_name) {
		return false;
	}
	map->comment = talloc_strdup(map, comment);
	if (!map->comment) {
		return false;
	}

	return true;
}
Пример #3
0
bool pdb_set_user_sid_from_string(struct samu *sampass, fstring u_sid, enum pdb_value_state flag)
{
	DOM_SID new_sid;

	if (!u_sid)
		return False;

	DEBUG(10, ("pdb_set_user_sid_from_string: setting user sid %s\n",
		   u_sid));

	if (!string_to_sid(&new_sid, u_sid)) { 
		DEBUG(1, ("pdb_set_user_sid_from_string: %s isn't a valid SID!\n", u_sid));
		return False;
	}

	if (!pdb_set_user_sid(sampass, &new_sid, flag)) {
		DEBUG(1, ("pdb_set_user_sid_from_string: could not set sid %s on struct samu!\n", u_sid));
		return False;
	}

	return True;
}
Пример #4
0
bool parse_sidlist(TALLOC_CTX *mem_ctx, const char *sidstr,
		   DOM_SID **sids, size_t *num_sids)
{
	const char *p, *q;

	p = sidstr;
	if (p == NULL)
		return False;

	while (p[0] != '\0') {
		fstring tmp;
		size_t sidlen;
		DOM_SID sid;
		q = strchr(p, '\n');
		if (q == NULL) {
			DEBUG(0, ("Got invalid sidstr: %s\n", p));
			return False;
		}
		sidlen = PTR_DIFF(q, p);
		if (sidlen >= sizeof(tmp)-1) {
			return false;
		}
		memcpy(tmp, p, sidlen);
		tmp[sidlen] = '\0';
		q += 1;
		if (!string_to_sid(&sid, tmp)) {
			DEBUG(0, ("Could not parse sid %s\n", p));
			return False;
		}
		if (!NT_STATUS_IS_OK(add_sid_to_array(mem_ctx, &sid, sids,
						      num_sids)))
		{
			return False;
		}
		p = q;
	}
	return True;
}
Пример #5
0
static NTSTATUS one_alias_membership(const DOM_SID *member,
			       DOM_SID **sids, size_t *num)
{
	fstring tmp;
	fstring key;
	char *string_sid;
	TDB_DATA dbuf;
	const char *p;
	NTSTATUS status = NT_STATUS_OK;
	TALLOC_CTX *frame = talloc_stackframe();

	slprintf(key, sizeof(key), "%s%s", MEMBEROF_PREFIX,
		 sid_to_fstring(tmp, member));

	dbuf = dbwrap_fetch_bystring(db, frame, key);
	if (dbuf.dptr == NULL) {
		TALLOC_FREE(frame);
		return NT_STATUS_OK;
	}

	p = (const char *)dbuf.dptr;

	while (next_token_talloc(frame, &p, &string_sid, " ")) {
		DOM_SID alias;

		if (!string_to_sid(&alias, string_sid))
			continue;

		status= add_sid_to_array_unique(NULL, &alias, sids, num);
		if (!NT_STATUS_IS_OK(status)) {
			goto done;
		}
	}

done:
	TALLOC_FREE(frame);
	return status;
}
Пример #6
0
/* convert a string to a SID, either numeric or username/group */
static BOOL StringToSid(DOM_SID *sid, const char *str)
{
	uint32 *types = NULL;
	DOM_SID *sids = NULL;
	BOOL result = True;

	if (strncmp(str, "S-", 2) == 0) {
		return string_to_sid(sid, str);
	}

	if (!cli_open_policy_hnd() ||
	    !NT_STATUS_IS_OK(cli_lsa_lookup_names(cli_ipc, cli_ipc->mem_ctx, 
						  &pol, 1, &str, &sids, 
						  &types))) {
		result = False;
		goto done;
	}

	sid_copy(sid, &sids[0]);
 done:

	return result;
}
Пример #7
0
/* convert a string to a SID, either numeric or username/group */
static bool StringToSid(struct dom_sid *sid, const char *str)
{
	enum lsa_SidType *types = NULL;
	struct dom_sid *sids = NULL;
	bool result = True;

	if (string_to_sid(sid, str)) {
		return true;
	}

	if (!cli_open_policy_hnd() ||
	    !NT_STATUS_IS_OK(rpccli_lsa_lookup_names(global_pipe_hnd, talloc_tos(),
						  &pol, 1, &str, NULL, 1, &sids, 
						  &types))) {
		result = False;
		goto done;
	}

	sid_copy(sid, &sids[0]);
 done:

	return result;
}
Пример #8
0
static bool
sid_in_ignore_list(struct dom_sid * sid, int snum)
{
	const char ** sid_list = NULL;
	struct dom_sid match;

	sid_list = lp_parm_string_list(snum, PARM_ONEFS_TYPE,
	    PARM_UNMAPPABLE_SIDS_IGNORE_LIST,
	    PARM_UNMAPPABLE_SIDS_IGNORE_LIST_DEFAULT);

	/* Fast path a NULL list */
	if (!sid_list || *sid_list == NULL)
		return false;

	while (*sid_list) {
		if (string_to_sid(&match, *sid_list))
			if (sid_equal(sid, &match))
				return true;
		sid_list++;
	}

	return false;
}
Пример #9
0
static BOOL mappable_sid(const DOM_SID *sid)
{
	DOM_SID domain_sid;
	
	if (sid_compare(sid, &global_sid_Builtin_Administrators) == 0)
		return True;

	if (sid_compare(sid, &global_sid_World) == 0)
		return True;

	if (sid_compare(sid, &global_sid_Authenticated_Users) == 0)
		return True;

	if (sid_compare(sid, &global_sid_Builtin_Backup_Operators) == 0)
		return True;

	string_to_sid(&domain_sid, "S-1-5-21");

	if (sid_compare_domain(sid, &domain_sid) == 0)
		return True;

	return False;
}
Пример #10
0
void generate_wellknown_sids(void)
{
	string_to_sid(&global_sid_Builtin, "S-1-5-32");
	string_to_sid(&global_sid_Builtin_Administrators, "S-1-5-32-544");
	string_to_sid(&global_sid_Builtin_Users, "S-1-5-32-545");
	string_to_sid(&global_sid_Builtin_Guests, "S-1-5-32-546");
	string_to_sid(&global_sid_World_Domain, "S-1-1");
	string_to_sid(&global_sid_World, "S-1-1-0");
	string_to_sid(&global_sid_Creator_Owner_Domain, "S-1-3");
	string_to_sid(&global_sid_Creator_Owner, "S-1-3-0");
	string_to_sid(&global_sid_Creator_Group, "S-1-3-1");
	string_to_sid(&global_sid_NT_Authority, "S-1-5");
	string_to_sid(&global_sid_NULL, "S-1-0-0");
	string_to_sid(&global_sid_Authenticated_Users, "S-1-5-11");
	string_to_sid(&global_sid_Network, "S-1-5-2");
	string_to_sid(&global_sid_Anonymous, "S-1-5-7");

	/* Create the anon token. */
	sid_copy( &anonymous_token.user_sids[0], &global_sid_World);
	sid_copy( &anonymous_token.user_sids[1], &global_sid_Network);
	sid_copy( &anonymous_token.user_sids[2], &global_sid_Anonymous);
}
Пример #11
0
void generate_wellknown_sids(void)
{
	static BOOL initialised = False;

	if (initialised) 
		return;

	/* SECURITY_NULL_SID_AUTHORITY */
	string_to_sid(&global_sid_NULL, "S-1-0-0");

	/* SECURITY_WORLD_SID_AUTHORITY */
	string_to_sid(&global_sid_World_Domain, "S-1-1");
	string_to_sid(&global_sid_World, "S-1-1-0");

	/* SECURITY_CREATOR_SID_AUTHORITY */
	string_to_sid(&global_sid_Creator_Owner_Domain, "S-1-3");
	string_to_sid(&global_sid_Creator_Owner, "S-1-3-0");
	string_to_sid(&global_sid_Creator_Group, "S-1-3-1");

	/* SECURITY_NT_AUTHORITY */
	string_to_sid(&global_sid_NT_Authority, "S-1-5");
	string_to_sid(&global_sid_Network, "S-1-5-2");
	string_to_sid(&global_sid_Anonymous, "S-1-5-7");
	string_to_sid(&global_sid_Authenticated_Users, "S-1-5-11");
	string_to_sid(&global_sid_System, "S-1-5-18");

	/* SECURITY_BUILTIN_DOMAIN_RID */
	string_to_sid(&global_sid_Builtin, "S-1-5-32");
	string_to_sid(&global_sid_Builtin_Administrators, "S-1-5-32-544");
	string_to_sid(&global_sid_Builtin_Users, "S-1-5-32-545");
	string_to_sid(&global_sid_Builtin_Guests, "S-1-5-32-546");
	string_to_sid(&global_sid_Builtin_Power_Users, "S-1-5-32-547");
	string_to_sid(&global_sid_Builtin_Account_Operators, "S-1-5-32-548");
	string_to_sid(&global_sid_Builtin_Server_Operators, "S-1-5-32-549");
	string_to_sid(&global_sid_Builtin_Print_Operators, "S-1-5-32-550");
	string_to_sid(&global_sid_Builtin_Backup_Operators, "S-1-5-32-551");
	string_to_sid(&global_sid_Builtin_Replicator, "S-1-5-32-552");

	/* Create the anon token. */
	sid_copy( &anonymous_token.user_sids[0], &global_sid_World);
	sid_copy( &anonymous_token.user_sids[1], &global_sid_Network);
	sid_copy( &anonymous_token.user_sids[2], &global_sid_Anonymous);

	/* Create the system token. */
	sid_copy( &system_token.user_sids[0], &global_sid_System);
	
	initialised = True;
}
Пример #12
0
BOOL parse_usershare_acl(TALLOC_CTX *ctx, const char *acl_str, SEC_DESC **ppsd)
{
	size_t s_size = 0;
	const char *pacl = acl_str;
	int num_aces = 0;
	SEC_ACE *ace_list = NULL;
	SEC_ACL *psa = NULL;
	SEC_DESC *psd = NULL;
	size_t sd_size = 0;
	int i;

	*ppsd = NULL;

	/* If the acl string is blank return "Everyone:R" */
	if (!*acl_str) {
		SEC_DESC *default_psd = get_share_security_default(ctx, &s_size, GENERIC_READ_ACCESS);
		if (!default_psd) {
			return False;
		}
		*ppsd = default_psd;
		return True;
	}

	num_aces = 1;

	/* Add the number of ',' characters to get the number of aces. */
	num_aces += count_chars(pacl,',');

	ace_list = TALLOC_ARRAY(ctx, SEC_ACE, num_aces);
	if (!ace_list) {
		return False;
	}

	for (i = 0; i < num_aces; i++) {
		SEC_ACCESS sa;
		uint32 g_access;
		uint32 s_access;
		DOM_SID sid;
		fstring sidstr;
		uint8 type = SEC_ACE_TYPE_ACCESS_ALLOWED;

		if (!next_token(&pacl, sidstr, ":", sizeof(sidstr))) {
			DEBUG(0,("parse_usershare_acl: malformed usershare acl looking "
				"for ':' in string '%s'\n", pacl));
			return False;
		}

		if (!string_to_sid(&sid, sidstr)) {
			DEBUG(0,("parse_usershare_acl: failed to convert %s to sid.\n",
				sidstr ));
			return False;
		}

		switch (*pacl) {
			case 'F': /* Full Control, ie. R+W */
			case 'f': /* Full Control, ie. R+W */
				s_access = g_access = GENERIC_ALL_ACCESS;
				break;
			case 'R': /* Read only. */
			case 'r': /* Read only. */
				s_access = g_access = GENERIC_READ_ACCESS;
				break;
			case 'D': /* Deny all to this SID. */
			case 'd': /* Deny all to this SID. */
				type = SEC_ACE_TYPE_ACCESS_DENIED;
				s_access = g_access = GENERIC_ALL_ACCESS;
				break;
			default:
				DEBUG(0,("parse_usershare_acl: unknown acl type at %s.\n",
					pacl ));
				return False;
		}

		pacl++;
		if (*pacl && *pacl != ',') {
			DEBUG(0,("parse_usershare_acl: bad acl string at %s.\n",
				pacl ));
			return False;
		}
		pacl++; /* Go past any ',' */

		se_map_generic(&s_access, &file_generic_mapping);
		init_sec_access(&sa, g_access | s_access );
		init_sec_ace(&ace_list[i], &sid, type, sa, 0);
	}

	if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, num_aces, ace_list)) != NULL) {
		psd = make_sec_desc(ctx, SEC_DESC_REVISION, SEC_DESC_SELF_RELATIVE, NULL, NULL, NULL, psa, &sd_size);
	}

	if (!psd) {
		DEBUG(0,("parse_usershare_acl: Failed to make SEC_DESC.\n"));
		return False;
	}

	*ppsd = psd;
	return True;
}
Пример #13
0
static bool parse_ace(SEC_ACE *ace, const char *orig_str)
{
	char *p;
	const char *cp;
	char *tok;
	unsigned int atype = 0;
	unsigned int aflags = 0;
	unsigned int amask = 0;
	DOM_SID sid;
	SEC_ACCESS mask;
	const struct perm_value *v;
	char *str = SMB_STRDUP(orig_str);
	TALLOC_CTX *frame = talloc_stackframe();

	if (!str) {
		TALLOC_FREE(frame);
		return False;
	}

	ZERO_STRUCTP(ace);
	p = strchr_m(str,':');
	if (!p) {
		printf("ACE '%s': missing ':'.\n", orig_str);
		SAFE_FREE(str);
		TALLOC_FREE(frame);
		return False;
	}
	*p = '\0';
	p++;
	/* Try to parse numeric form */

	if (sscanf(p, "%i/%i/%i", &atype, &aflags, &amask) == 3 &&
	    string_to_sid(&sid, str)) {
		goto done;
	}

	/* Try to parse text form */

	if (!string_to_sid(&sid, str)) {
		printf("ACE '%s': failed to convert '%s' to SID\n",
			orig_str, str);
		SAFE_FREE(str);
		TALLOC_FREE(frame);
		return False;
	}

	cp = p;
	if (!next_token_talloc(frame, &cp, &tok, "/")) {
		printf("ACE '%s': failed to find '/' character.\n",
			orig_str);
		SAFE_FREE(str);
		TALLOC_FREE(frame);
		return False;
	}

	if (strncmp(tok, "ALLOWED", strlen("ALLOWED")) == 0) {
		atype = SEC_ACE_TYPE_ACCESS_ALLOWED;
	} else if (strncmp(tok, "DENIED", strlen("DENIED")) == 0) {
		atype = SEC_ACE_TYPE_ACCESS_DENIED;
	} else {
		printf("ACE '%s': missing 'ALLOWED' or 'DENIED' entry at '%s'\n",
			orig_str, tok);
		SAFE_FREE(str);
		TALLOC_FREE(frame);
		return False;
	}

	/* Only numeric form accepted for flags at present */
	/* no flags on share permissions */

	if (!(next_token_talloc(frame, &cp, &tok, "/") &&
	      sscanf(tok, "%i", &aflags) && aflags == 0)) {
		printf("ACE '%s': bad integer flags entry at '%s'\n",
			orig_str, tok);
		SAFE_FREE(str);
		TALLOC_FREE(frame);
		return False;
	}

	if (!next_token_talloc(frame, &cp, &tok, "/")) {
		printf("ACE '%s': missing / at '%s'\n",
			orig_str, tok);
		SAFE_FREE(str);
		TALLOC_FREE(frame);
		return False;
	}

	if (strncmp(tok, "0x", 2) == 0) {
		if (sscanf(tok, "%i", &amask) != 1) {
			printf("ACE '%s': bad hex number at '%s'\n",
				orig_str, tok);
			TALLOC_FREE(frame);
			SAFE_FREE(str);
			return False;
		}
		goto done;
	}

	for (v = standard_values; v->perm; v++) {
		if (strcmp(tok, v->perm) == 0) {
			amask = v->mask;
			goto done;
		}
	}

	p = tok;

	while(*p) {
		bool found = False;

		for (v = special_values; v->perm; v++) {
			if (v->perm[0] == *p) {
				amask |= v->mask;
				found = True;
			}
		}

		if (!found) {
			printf("ACE '%s': bad permission value at '%s'\n",
				orig_str, p);
			TALLOC_FREE(frame);
			SAFE_FREE(str);
		 	return False;
		}
		p++;
	}

	if (*p) {
		TALLOC_FREE(frame);
		SAFE_FREE(str);
		return False;
	}

 done:
	mask = amask;
	init_sec_ace(ace, &sid, atype, mask, aflags);
	SAFE_FREE(str);
	TALLOC_FREE(frame);
	return True;
}
Пример #14
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;
}
Пример #15
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;
}
Пример #16
0
static bool token_contains_name(TALLOC_CTX *mem_ctx,
				const char *username,
				const char *domain,
				const char *sharename,
				const struct nt_user_token *token,
				const char *name)
{
	const char *prefix;
	DOM_SID sid;
	enum lsa_SidType type;
	struct smbd_server_connection *sconn = smbd_server_conn;

	if (username != NULL) {
		name = talloc_sub_basic(mem_ctx, username, domain, name);
	}
	if (sharename != NULL) {
		name = talloc_string_sub(mem_ctx, name, "%S", sharename);
	}

	if (name == NULL) {
		/* This is too security sensitive, better panic than return a
		 * result that might be interpreted in a wrong way. */
		smb_panic("substitutions failed");
	}
	
	/* check to see is we already have a SID */

	if ( string_to_sid( &sid, name ) ) {
		DEBUG(5,("token_contains_name: Checking for SID [%s] in token\n", name));
		return nt_token_check_sid( &sid, token );
	}

	if (!do_group_checks(&name, &prefix)) {
		if (!lookup_name_smbconf(mem_ctx, name, LOOKUP_NAME_ALL,
				 NULL, NULL, &sid, &type)) {
			DEBUG(5, ("lookup_name %s failed\n", name));
			return False;
		}
		if (type != SID_NAME_USER) {
			DEBUG(5, ("%s is a %s, expected a user\n",
				  name, sid_type_lookup(type)));
			return False;
		}
		return nt_token_check_sid(&sid, token);
	}

	for (/* initialized above */ ; *prefix != '\0'; prefix++) {
		if (*prefix == '+') {
			if (!lookup_name_smbconf(mem_ctx, name,
					 LOOKUP_NAME_ALL|LOOKUP_NAME_GROUP,
					 NULL, NULL, &sid, &type)) {
				DEBUG(5, ("lookup_name %s failed\n", name));
				return False;
			}
			if ((type != SID_NAME_DOM_GRP) &&
			    (type != SID_NAME_ALIAS) &&
			    (type != SID_NAME_WKN_GRP)) {
				DEBUG(5, ("%s is a %s, expected a group\n",
					  name, sid_type_lookup(type)));
				return False;
			}
			if (nt_token_check_sid(&sid, token)) {
				return True;
			}
			continue;
		}
		if (*prefix == '&') {
			if (username) {
				if (user_in_netgroup(sconn, username, name)) {
					return True;
				}
			}
			continue;
		}
		smb_panic("got invalid prefix from do_groups_check");
	}
	return False;
}
Пример #17
0
static NTSTATUS idmap_tdb_id_to_sid(struct idmap_domain *dom, struct id_map *map)
{
	NTSTATUS ret;
	TDB_DATA data;
	char *keystr;
	struct idmap_tdb_context *ctx;

	if (!dom || !map) {
		return NT_STATUS_INVALID_PARAMETER;
	}

	ctx = talloc_get_type(dom->private_data, struct idmap_tdb_context);

	/* apply filters before checking */
	if (!idmap_unix_id_is_in_range(map->xid.id, dom)) {
		DEBUG(5, ("Requested id (%u) out of range (%u - %u). Filtered!\n",
				map->xid.id, dom->low_id, dom->high_id));
		return NT_STATUS_NONE_MAPPED;
	}

	switch (map->xid.type) {

	case ID_TYPE_UID:
		keystr = talloc_asprintf(ctx, "UID %lu", (unsigned long)map->xid.id);
		break;

	case ID_TYPE_GID:
		keystr = talloc_asprintf(ctx, "GID %lu", (unsigned long)map->xid.id);
		break;

	default:
		DEBUG(2, ("INVALID unix ID type: 0x02%x\n", map->xid.type));
		return NT_STATUS_INVALID_PARAMETER;
	}

	/* final SAFE_FREE safe */
	data.dptr = NULL;

	if (keystr == NULL) {
		DEBUG(0, ("Out of memory!\n"));
		ret = NT_STATUS_NO_MEMORY;
		goto done;
	}

	DEBUG(10,("Fetching record %s\n", keystr));

	/* Check if the mapping exists */
	ret = dbwrap_fetch_bystring(ctx->db, NULL, keystr, &data);

	if (!NT_STATUS_IS_OK(ret)) {
		DEBUG(10,("Record %s not found\n", keystr));
		ret = NT_STATUS_NONE_MAPPED;
		goto done;
	}

	if (!string_to_sid(map->sid, (const char *)data.dptr)) {
		DEBUG(10,("INVALID SID (%s) in record %s\n",
			(const char *)data.dptr, keystr));
		ret = NT_STATUS_INTERNAL_DB_ERROR;
		goto done;
	}

	DEBUG(10,("Found record %s -> %s\n", keystr, (const char *)data.dptr));
	ret = NT_STATUS_OK;

done:
	talloc_free(data.dptr);
	talloc_free(keystr);
	return ret;
}
Пример #18
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;
}
Пример #19
0
static void parse_samsync_partial_replication_objects(TALLOC_CTX *mem_ctx,
						      int argc,
						      const char **argv,
						      bool *do_single_object_replication,
						      struct samsync_object **objects,
						      uint32_t *num_objects)
{
	int i;

	if (argc > 0) {
		*do_single_object_replication = true;
	}

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

		struct samsync_object o;

		ZERO_STRUCT(o);

		if (!StrnCaseCmp(argv[i], "user_rid=", strlen("user_rid="))) {
			o.object_identifier.rid		= get_int_param(argv[i]);
			o.object_type			= NETR_DELTA_USER;
			o.database_id			= SAM_DATABASE_DOMAIN;
		}
		if (!StrnCaseCmp(argv[i], "group_rid=", strlen("group_rid="))) {
			o.object_identifier.rid		= get_int_param(argv[i]);
			o.object_type			= NETR_DELTA_GROUP;
			o.database_id			= SAM_DATABASE_DOMAIN;
		}
		if (!StrnCaseCmp(argv[i], "group_member_rid=", strlen("group_member_rid="))) {
			o.object_identifier.rid		= get_int_param(argv[i]);
			o.object_type			= NETR_DELTA_GROUP_MEMBER;
			o.database_id			= SAM_DATABASE_DOMAIN;
		}
		if (!StrnCaseCmp(argv[i], "alias_rid=", strlen("alias_rid="))) {
			o.object_identifier.rid		= get_int_param(argv[i]);
			o.object_type			= NETR_DELTA_ALIAS;
			o.database_id			= SAM_DATABASE_BUILTIN;
		}
		if (!StrnCaseCmp(argv[i], "alias_member_rid=", strlen("alias_member_rid="))) {
			o.object_identifier.rid		= get_int_param(argv[i]);
			o.object_type			= NETR_DELTA_ALIAS_MEMBER;
			o.database_id			= SAM_DATABASE_BUILTIN;
		}
		if (!StrnCaseCmp(argv[i], "account_sid=", strlen("account_sid="))) {
			const char *sid_str = get_string_param(argv[i]);
			string_to_sid(&o.object_identifier.sid, sid_str);
			o.object_type			= NETR_DELTA_ACCOUNT;
			o.database_id			= SAM_DATABASE_PRIVS;
		}
		if (!StrnCaseCmp(argv[i], "policy_sid=", strlen("policy_sid="))) {
			const char *sid_str = get_string_param(argv[i]);
			string_to_sid(&o.object_identifier.sid, sid_str);
			o.object_type			= NETR_DELTA_POLICY;
			o.database_id			= SAM_DATABASE_PRIVS;
		}
		if (!StrnCaseCmp(argv[i], "trustdom_sid=", strlen("trustdom_sid="))) {
			const char *sid_str = get_string_param(argv[i]);
			string_to_sid(&o.object_identifier.sid, sid_str);
			o.object_type			= NETR_DELTA_TRUSTED_DOMAIN;
			o.database_id			= SAM_DATABASE_PRIVS;
		}
		if (!StrnCaseCmp(argv[i], "secret_name=", strlen("secret_name="))) {
			o.object_identifier.name	= get_string_param(argv[i]);
			o.object_type			= NETR_DELTA_SECRET;
			o.database_id			= SAM_DATABASE_PRIVS;
		}

		if (o.object_type > 0) {
			ADD_TO_ARRAY(mem_ctx, struct samsync_object, o,
				     objects, num_objects);
		}
	}
}
Пример #20
0
enum winbindd_result winbindd_sid_to_gid(struct winbindd_cli_state *state)
{
	DOM_SID sid;
	uint32 flags = 0x0;

	/* Ensure null termination */
	state->request.data.sid[sizeof(state->request.data.sid)-1]='\0';

	DEBUG(3, ("[%5lu]: sid to gid %s\n", (unsigned long)state->pid, 
		  state->request.data.sid));

	if (!string_to_sid(&sid, state->request.data.sid)) {
		DEBUG(1, ("Could not cvt string to sid %s\n", state->request.data.sid));
		return WINBINDD_ERROR;
	}

	/* This gets a little tricky.  If we assume that usernames are syncd between
	   /etc/passwd and the windows domain (such as a member of a Samba domain),
	   the we need to get the uid from the OS and not alocate one ourselves */
	   
	if ( lp_winbind_trusted_domains_only() ) {
		struct winbindd_domain *domain = NULL;
		DOM_SID sid2;
		uint32 rid;
		unid_t id;
		
		domain = find_our_domain();
		if ( !domain ) {
			DEBUG(0,("winbindd_sid_to_uid: can't find my own domain!\n"));
			return WINBINDD_ERROR;
		}
		
		sid_copy( &sid2, &sid );
		sid_split_rid( &sid2, &rid );

		if ( sid_equal( &sid2, &domain->sid ) ) {
		
			fstring domain_name;
			fstring group;
			enum SID_NAME_USE type;
			struct group *grp = NULL;
			
			/* ok...here's we know that we are dealing with our
			   own domain (the one to which we are joined).  And
			   we know that there must be a UNIX account for this group.
			   So we lookup the sid and the call getpwnam().*/
			
			/* But first check and see if we don't already have a mapping */
			   
			flags = ID_QUERY_ONLY;
			if ( NT_STATUS_IS_OK(idmap_sid_to_gid(&sid, &(state->response.data.gid), flags)) )
				return WINBINDD_OK;
				
			/* now fall back to the hard way */
			
			if ( !winbindd_lookup_name_by_sid(&sid, domain_name, group, &type) )
				return WINBINDD_ERROR;
				
			if ( !(grp = sys_getgrnam(group)) ) {
				DEBUG(0,("winbindd_sid_to_uid: 'winbind trusted domains only' is "
					"set but this group [%s] doesn't exist!\n", group));
				return WINBINDD_ERROR;
			}
			
			state->response.data.gid = grp->gr_gid;

			id.gid = grp->gr_gid;
			idmap_set_mapping( &sid, id, ID_GROUPID );

			return WINBINDD_OK;
		}

	}
	
	if ( state->request.flags & WBFLAG_QUERY_ONLY ) 
		flags = ID_QUERY_ONLY;
		
	/* Find gid for this sid and return it */
	if ( !NT_STATUS_IS_OK(idmap_sid_to_gid(&sid, &(state->response.data.gid), flags)) ) {
		DEBUG(1, ("Could not get gid for sid %s\n", state->request.data.sid));
		return WINBINDD_ERROR;
	}

	return WINBINDD_OK;
}
Пример #21
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;
}
Пример #22
0
static NTSTATUS cmd_samr_lookup_names(struct cli_state *cli, 
                                      TALLOC_CTX *mem_ctx,
                                      int argc, char **argv) 
{
	NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
	POLICY_HND connect_pol, domain_pol;
	uint32 flags = 0x000003e8; /* Unknown */
	uint32 num_rids, num_names, *name_types, *rids;
	const char **names;
	int i;
	DOM_SID global_sid_Builtin;

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

	if (argc < 3) {
		printf("Usage: %s  domain|builtin name1 [name2 [name3] [...]]\n", argv[0]);
		printf("check on the domain SID: S-1-5-21-x-y-z\n");
		printf("or check on the builtin SID: S-1-5-32\n");
		return NT_STATUS_OK;
	}

	/* Get sam policy and domain handles */

	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;
	}

	/* Look up names */

	num_names = argc - 2;
	names = (const char **)talloc(mem_ctx, sizeof(char *) * num_names);

	for (i = 0; i < argc - 2; i++)
		names[i] = argv[i + 2];

	result = cli_samr_lookup_names(cli, mem_ctx, &domain_pol,
				       flags, num_names, names,
				       &num_rids, &rids, &name_types);

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

	/* Display results */

	for (i = 0; i < num_names; i++)
		printf("name %s: 0x%x (%d)\n", names[i], rids[i], 
		       name_types[i]);

 done:
	return result;
}
Пример #23
0
static NTSTATUS idmap_ldap_sids_to_unixids(struct idmap_domain *dom,
					   struct id_map **ids)
{
	LDAPMessage *entry = NULL;
	NTSTATUS ret;
	TALLOC_CTX *memctx;
	struct idmap_ldap_context *ctx;
	LDAPMessage *result = NULL;
	const char *uidNumber;
	const char *gidNumber;
	const char **attr_list;
	char *filter = NULL;
	bool multi = False;
	int idx = 0;
	int bidx = 0;
	int count;
	int rc;
	int i;

	/* Only do query if we are online */
	if (idmap_is_offline())	{
		return NT_STATUS_FILE_IS_OFFLINE;
	}

	ctx = talloc_get_type(dom->private_data, struct idmap_ldap_context);

	memctx = talloc_new(ctx);
	if ( ! memctx) {
		DEBUG(0, ("Out of memory!\n"));
		return NT_STATUS_NO_MEMORY;
	}

	uidNumber = get_attr_key2string(idpool_attr_list, LDAP_ATTR_UIDNUMBER);
	gidNumber = get_attr_key2string(idpool_attr_list, LDAP_ATTR_GIDNUMBER);

	attr_list = get_attr_list(memctx, sidmap_attr_list);

	if ( ! ids[1]) {
		/* if we are requested just one mapping use the simple filter */

		filter = talloc_asprintf(memctx, "(&(objectClass=%s)(%s=%s))",
				LDAP_OBJ_IDMAP_ENTRY,
				LDAP_ATTRIBUTE_SID,
				sid_string_talloc(memctx, ids[0]->sid));
		CHECK_ALLOC_DONE(filter);
		DEBUG(10, ("Filter: [%s]\n", filter));
	} else {
		/* multiple mappings */
		multi = True;
	}

	for (i = 0; ids[i]; i++) {
		ids[i]->status = ID_UNKNOWN;
	}

again:
	if (multi) {

		TALLOC_FREE(filter);
		filter = talloc_asprintf(memctx,
					 "(&(objectClass=%s)(|",
					 LDAP_OBJ_IDMAP_ENTRY);
		CHECK_ALLOC_DONE(filter);

		bidx = idx;
		for (i = 0; (i < IDMAP_LDAP_MAX_IDS) && ids[idx]; i++, idx++) {
			filter = talloc_asprintf_append_buffer(filter, "(%s=%s)",
					LDAP_ATTRIBUTE_SID,
					sid_string_talloc(memctx,
							  ids[idx]->sid));
			CHECK_ALLOC_DONE(filter);
		}
		filter = talloc_asprintf_append_buffer(filter, "))");
		CHECK_ALLOC_DONE(filter);
		DEBUG(10, ("Filter: [%s]", filter));
	} else {
		bidx = 0;
		idx = 1;
	}

	rc = smbldap_search(ctx->smbldap_state, ctx->suffix, LDAP_SCOPE_SUBTREE,
		filter, attr_list, 0, &result);

	if (rc != LDAP_SUCCESS) {
		DEBUG(3,("Failure looking up sids (%s)\n",
			 ldap_err2string(rc)));
		ret = NT_STATUS_UNSUCCESSFUL;
		goto done;
	}

	count = ldap_count_entries(ctx->smbldap_state->ldap_struct, result);

	if (count == 0) {
		DEBUG(10, ("NO SIDs found\n"));
	}

	for (i = 0; i < count; i++) {
		char *sidstr = NULL;
		char *tmp = NULL;
		enum id_type type;
		struct id_map *map;
		struct dom_sid sid;
		uint32_t id;

		if (i == 0) { /* first entry */
			entry = ldap_first_entry(ctx->smbldap_state->ldap_struct,
						 result);
		} else { /* following ones */
			entry = ldap_next_entry(ctx->smbldap_state->ldap_struct,
						entry);
		}
		if ( ! entry) {
			DEBUG(2, ("ERROR: Unable to fetch ldap entries "
				  "from results\n"));
			break;
		}

		/* first check if the SID is present */
		sidstr = smbldap_talloc_single_attribute(
				ctx->smbldap_state->ldap_struct,
				entry, LDAP_ATTRIBUTE_SID, memctx);
		if ( ! sidstr) { /* no sid ??, skip entry */
			DEBUG(2, ("WARNING SID not found on entry\n"));
			continue;
		}

		if ( ! string_to_sid(&sid, sidstr)) {
			DEBUG(2, ("ERROR: Invalid SID on entry\n"));
			TALLOC_FREE(sidstr);
			continue;
		}

		map = idmap_find_map_by_sid(&ids[bidx], &sid);
		if (!map) {
			DEBUG(2, ("WARNING: couldn't find entry sid (%s) "
				  "in ids", sidstr));
			TALLOC_FREE(sidstr);
			continue;
		}

		/* now try to see if it is a uid, if not try with a gid
		 * (gid is more common, but in case both uidNumber and
		 * gidNumber are returned the SID is mapped to the uid
		 * not the gid) */
		type = ID_TYPE_UID;
		tmp = smbldap_talloc_single_attribute(
				ctx->smbldap_state->ldap_struct,
				entry, uidNumber, memctx);
		if ( ! tmp) {
			type = ID_TYPE_GID;
			tmp = smbldap_talloc_single_attribute(
					ctx->smbldap_state->ldap_struct,
					entry, gidNumber, memctx);
		}
		if ( ! tmp) { /* no ids ?? */
			DEBUG(5, ("no uidNumber, "
				  "nor gidNumber attributes found\n"));
			TALLOC_FREE(sidstr);
			continue;
		}

		id = strtoul(tmp, NULL, 10);
		if (!idmap_unix_id_is_in_range(id, dom)) {
			DEBUG(5, ("Requested id (%u) out of range (%u - %u). "
				  "Filtered!\n", id,
				  dom->low_id, dom->high_id));
			TALLOC_FREE(sidstr);
			TALLOC_FREE(tmp);
			continue;
		}
		TALLOC_FREE(tmp);

		if (map->status == ID_MAPPED) {
			DEBUG(1, ("WARNING: duplicate %s mapping in LDAP. "
			      "overwriting mapping %s -> %u with %s -> %u\n",
			      (type == ID_TYPE_UID) ? "UID" : "GID",
			      sidstr, map->xid.id, sidstr, id));
		}

		TALLOC_FREE(sidstr);

		/* mapped */
		map->xid.type = type;
		map->xid.id = id;
		map->status = ID_MAPPED;

		DEBUG(10, ("Mapped %s -> %lu (%d)\n", sid_string_dbg(map->sid),
			   (unsigned long)map->xid.id, map->xid.type));
	}

	/* free the ldap results */
	if (result) {
		ldap_msgfree(result);
		result = NULL;
	}

	if (multi && ids[idx]) { /* still some values to map */
		goto again;
	}

	/*
	 *  try to create new mappings for unmapped sids
	 */
	for (i = 0; ids[i]; i++) {
		if (ids[i]->status != ID_MAPPED) {
			ids[i]->status = ID_UNMAPPED;
			if (ids[i]->sid != NULL) {
				ret = idmap_ldap_new_mapping(dom, ids[i]);
				if (!NT_STATUS_IS_OK(ret)) {
					goto done;
				}
			}
		}
	}

	ret = NT_STATUS_OK;

done:
	talloc_free(memctx);
	return ret;
}
Пример #24
0
static NTSTATUS cmd_lsa_lookup_sids(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
                                    int argc, const char **argv)
{
	struct policy_handle pol;
	NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
	DOM_SID *sids;
	char **domains;
	char **names;
	enum lsa_SidType *types;
	int i;

	if (argc == 1) {
		printf("Usage: %s [sid1 [sid2 [...]]]\n", argv[0]);
		return NT_STATUS_OK;
	}

	result = rpccli_lsa_open_policy(cli, mem_ctx, True, 
				     SEC_FLAG_MAXIMUM_ALLOWED,
				     &pol);

	if (!NT_STATUS_IS_OK(result))
		goto done;

	/* Convert arguments to sids */

	sids = TALLOC_ARRAY(mem_ctx, DOM_SID, argc - 1);

	if (!sids) {
		printf("could not allocate memory for %d sids\n", argc - 1);
		goto done;
	}

	for (i = 0; i < argc - 1; i++) 
		if (!string_to_sid(&sids[i], argv[i + 1])) {
			result = NT_STATUS_INVALID_SID;
			goto done;
		}

	/* Lookup the SIDs */

	result = rpccli_lsa_lookup_sids(cli, mem_ctx, &pol, argc - 1, sids, 
				     &domains, &names, &types);

	if (!NT_STATUS_IS_OK(result) && NT_STATUS_V(result) != 
	    NT_STATUS_V(STATUS_SOME_UNMAPPED))
		goto done;

	result = NT_STATUS_OK;

	/* Print results */

	for (i = 0; i < (argc - 1); i++) {
		fstring sid_str;

		sid_to_fstring(sid_str, &sids[i]);
		printf("%s %s\\%s (%d)\n", sid_str, 
		       domains[i] ? domains[i] : "*unknown*", 
		       names[i] ? names[i] : "*unknown*", types[i]);
	}

	rpccli_lsa_Close(cli, mem_ctx, &pol);

 done:
	return result;
}
Пример #25
0
int main( int argc, char *argv[] )
{
	TALLOC_CTX *frame = talloc_stackframe();
	int opt;
	REGF_FILE *infile, *outfile;
	REGF_NK_REC *nk;
	char *orig_filename, *new_filename;
	struct poptOption long_options[] = {
		POPT_AUTOHELP
		{ "change-sid", 'c', POPT_ARG_STRING, NULL, 'c', "Provides SID to change" },
		{ "new-sid", 'n', POPT_ARG_STRING, NULL, 'n', "Provides SID to change to" },
		{ "verbose", 'v', POPT_ARG_NONE, &opt_verbose, 'v', "Verbose output" },
		POPT_COMMON_SAMBA
		POPT_COMMON_VERSION
		POPT_TABLEEND
	};
	poptContext pc;

	load_case_tables();

	/* setup logging options */

	setup_logging( "profiles", DEBUG_STDERR);

	pc = poptGetContext("profiles", argc, (const char **)argv, long_options,
		POPT_CONTEXT_KEEP_FIRST);

	poptSetOtherOptionHelp(pc, "<profilefile>");

	/* Now, process the arguments */

	while ((opt = poptGetNextOpt(pc)) != -1) {
		switch (opt) {
		case 'c':
			change = 1;
			if (!string_to_sid(&old_sid, poptGetOptArg(pc))) {
				fprintf(stderr, "Argument to -c should be a SID in form of S-1-5-...\n");
				poptPrintUsage(pc, stderr, 0);
				exit(254);
			}
			break;

		case 'n':
			new_val = 1;
			if (!string_to_sid(&new_sid, poptGetOptArg(pc))) {
				fprintf(stderr, "Argument to -n should be a SID in form of S-1-5-...\n");
				poptPrintUsage(pc, stderr, 0);
				exit(253);
			}
			break;

		}
	}

	poptGetArg(pc);

	if (!poptPeekArg(pc)) {
		poptPrintUsage(pc, stderr, 0);
		exit(1);
	}

	if ((!change && new_val) || (change && !new_val)) {
		fprintf(stderr, "You must specify both -c and -n if one or the other is set!\n");
		poptPrintUsage(pc, stderr, 0);
		exit(252);
	}

	orig_filename = talloc_strdup(frame, poptPeekArg(pc));
	if (!orig_filename) {
		exit(ENOMEM);
	}
	new_filename = talloc_asprintf(frame,
					"%s.new",
					orig_filename);
	if (!new_filename) {
		exit(ENOMEM);
	}

	if (!(infile = regfio_open( orig_filename, O_RDONLY, 0))) {
		fprintf( stderr, "Failed to open %s!\n", orig_filename );
		fprintf( stderr, "Error was (%s)\n", strerror(errno) );
		exit (1);
	}

	if ( !(outfile = regfio_open( new_filename, (O_RDWR|O_CREAT|O_TRUNC),
				      (S_IRUSR|S_IWUSR) )) ) {
		fprintf( stderr, "Failed to open new file %s!\n", new_filename );
		fprintf( stderr, "Error was (%s)\n", strerror(errno) );
		exit (1);
	}

	/* actually do the update now */

	if ((nk = regfio_rootkey( infile )) == NULL) {
		fprintf(stderr, "Could not get rootkey\n");
		exit(3);
	}

	if (!copy_registry_tree( infile, nk, NULL, outfile, "")) {
		fprintf(stderr, "Failed to write updated registry file!\n");
		exit(2);
	}

	/* cleanup */

	regfio_close(infile);
	regfio_close(outfile);

	poptFreeContext(pc);

	TALLOC_FREE(frame);
	return 0;
}
Пример #26
0
static int ADC_client_on_recv_line(struct ADC_client* client, const char* line, size_t length)
{
	struct ADC_chat_message chat;
	struct ADC_client_callback_data data;

	ADC_TRACE;
#ifdef ADC_CLIENT_DEBUG_PROTO
	ADC_client_debug(client, "- LINE: '%s'", line);
#endif

	/* Parse message */
	struct adc_message* msg = adc_msg_parse(line, length);
	if (!msg)
	{
		ADC_client_debug(client, "WARNING: Message cannot be decoded: \"%s\"", line);
		return -1;
	}

	if (length < 4)
	{
		ADC_client_debug(client, "Unexpected response from hub: '%s'", line);
		return -1;
	}

	switch (msg->cmd)
	{
		case ADC_CMD_ISUP:
			break;

		case ADC_CMD_ISID:
			if (client->state == ps_protocol)
			{
				client->sid = string_to_sid(&line[5]);
				client->callback(client, ADC_CLIENT_LOGGING_IN, 0);
				ADC_client_set_state(client, ps_identify);
				ADC_client_send_info(client);
			}
			break;

		case ADC_CMD_BMSG:
		case ADC_CMD_EMSG:
		case ADC_CMD_DMSG:
		case ADC_CMD_IMSG:
		{
			chat.from_sid       = msg->source;
			chat.to_sid         = msg->target;
			data.chat = &chat;
			EXTRACT_POS_ARG(msg, 0, chat.message);
			chat.flags = 0;

			if (adc_msg_has_named_argument(msg, ADC_MSG_FLAG_ACTION))
				chat.flags |= chat_flags_action;

			if (adc_msg_has_named_argument(msg, ADC_MSG_FLAG_PRIVATE))
				chat.flags |= chat_flags_private;

			client->callback(client, ADC_CLIENT_MESSAGE, &data);
			hub_free(chat.message);
			break;
		}

		case ADC_CMD_IINF:
		{
			struct ADC_hub_info hubinfo;
			EXTRACT_NAMED_ARG(msg, "NI", hubinfo.name);
			EXTRACT_NAMED_ARG(msg, "DE", hubinfo.description);
			EXTRACT_NAMED_ARG(msg, "VE", hubinfo.version);

			struct ADC_client_callback_data data;
			data.hubinfo = &hubinfo;
			client->callback(client, ADC_CLIENT_HUB_INFO, &data);
			hub_free(hubinfo.name);
			hub_free(hubinfo.description);
			hub_free(hubinfo.version);
			break;
		}

		case ADC_CMD_BSCH:
		case ADC_CMD_FSCH:
		{
			client->callback(client, ADC_CLIENT_SEARCH_REQ, 0);
			break;
		}

		case ADC_CMD_BINF:
		{
			if (msg->source == client->sid)
			{
				if (client->state == ps_verify || client->state == ps_identify)
				{
					ADC_client_on_login(client);
				}
			}
			else
			{
				if (adc_msg_has_named_argument(msg, "ID"))
				{
					struct ADC_user user;
					user.sid = msg->source;
					EXTRACT_NAMED_ARG_X(msg, "NI", user.name, sizeof(user.name));
					EXTRACT_NAMED_ARG_X(msg, "DE", user.description, sizeof(user.description));
					EXTRACT_NAMED_ARG_X(msg, "VE", user.version, sizeof(user.version));
					EXTRACT_NAMED_ARG_X(msg, "ID", user.cid, sizeof(user.cid));
					EXTRACT_NAMED_ARG_X(msg, "I4", user.address, sizeof(user.address));

					struct ADC_client_callback_data data;
					data.user = &user;
					client->callback(client, ADC_CLIENT_USER_JOIN, &data);
				}
			}
		}
		break;

		case ADC_CMD_IQUI:
		{
			struct ADC_client_quit_reason reason;
			memset(&reason, 0, sizeof(reason));
			reason.sid = string_to_sid(&line[5]);

			if (adc_msg_has_named_argument(msg, ADC_QUI_FLAG_DISCONNECT))
				reason.flags |= 1;

			data.quit = &reason;
			client->callback(client, ADC_CLIENT_USER_QUIT, &data);
			break;
		}

		case ADC_CMD_ISTA:
			/*
			if (strncmp(line, "ISTA 000", 8))
			{
				ADC_client_debug(client, "status: '%s'\n", (start + 9));
			}
			*/
			break;

		default:
			break;
	}

	adc_msg_free(msg);
	return 0;
}
Пример #27
0
static int net_groupmap_set(struct net_context *c, int argc, const char **argv)
{
	const char *ntgroup = NULL;
	struct group *grp = NULL;
	GROUP_MAP *map;
	bool have_map = false;

	if ((argc < 1) || (argc > 2) || c->display_usage) {
		d_printf("%s\n%s",
			 _("Usage:"),
			 _(" net groupmap set \"NT Group\" "
			   "[\"unix group\"] [-C \"comment\"] [-L] [-D]\n"));
		return -1;
	}

	if ( c->opt_localgroup && c->opt_domaingroup ) {
		d_printf(_("Can only specify -L or -D, not both\n"));
		return -1;
	}

	ntgroup = argv[0];

	if (argc == 2) {
		grp = getgrnam(argv[1]);

		if (grp == NULL) {
			d_fprintf(stderr, _("Could not find unix group %s\n"),
				  argv[1]);
			return -1;
		}
	}

	map = talloc_zero(NULL, GROUP_MAP);
	if (!map) {
		d_printf(_("Out of memory!\n"));
		return -1;
	}

	have_map = pdb_getgrnam(map, ntgroup);

	if (!have_map) {
		struct dom_sid sid;
		have_map = ( (strncmp(ntgroup, "S-", 2) == 0) &&
			     string_to_sid(&sid, ntgroup) &&
			     pdb_getgrsid(map, sid) );
	}

	if (!have_map) {

		/* Ok, add it */

		if (grp == NULL) {
			d_fprintf(stderr,
				  _("Could not find group mapping for %s\n"),
				  ntgroup);
			TALLOC_FREE(map);
			return -1;
		}

		map->gid = grp->gr_gid;

		if (c->opt_rid == 0) {
			if ( pdb_capabilities() & PDB_CAP_STORE_RIDS ) {
				if ( !pdb_new_rid((uint32*)&c->opt_rid) ) {
					d_fprintf( stderr,
					    _("Could not allocate new RID\n"));
					TALLOC_FREE(map);
					return -1;
				}
			} else {
				c->opt_rid = algorithmic_pdb_gid_to_group_rid(map->gid);
			}
		}

		sid_compose(&map->sid, get_global_sam_sid(), c->opt_rid);

		map->sid_name_use = SID_NAME_DOM_GRP;
		map->nt_name = talloc_strdup(map, ntgroup);
		map->comment = talloc_strdup(map, "");
		if (!map->nt_name || !map->comment) {
			d_printf(_("Out of memory!\n"));
			TALLOC_FREE(map);
			return -1;
		}

		if (!NT_STATUS_IS_OK(pdb_add_group_mapping_entry(map))) {
			d_fprintf(stderr,
				  _("Could not add mapping entry for %s\n"),
				  ntgroup);
			TALLOC_FREE(map);
			return -1;
		}
	}

	/* Now we have a mapping entry, update that stuff */

	if ( c->opt_localgroup || c->opt_domaingroup ) {
		if (map->sid_name_use == SID_NAME_WKN_GRP) {
			d_fprintf(stderr,
				  _("Can't change type of the BUILTIN "
				    "group %s\n"),
				  map->nt_name);
			TALLOC_FREE(map);
			return -1;
		}
	}

	if (c->opt_localgroup)
		map->sid_name_use = SID_NAME_ALIAS;

	if (c->opt_domaingroup)
		map->sid_name_use = SID_NAME_DOM_GRP;

	/* The case (opt_domaingroup && opt_localgroup) was tested for above */

	if ((c->opt_comment != NULL) && (strlen(c->opt_comment) > 0)) {
		map->comment = talloc_strdup(map, c->opt_comment);
		if (!map->comment) {
			d_printf(_("Out of memory!\n"));
			TALLOC_FREE(map);
			return -1;
		}
	}

	if ((c->opt_newntname != NULL) && (strlen(c->opt_newntname) > 0)) {
		map->nt_name = talloc_strdup(map, c->opt_newntname);
		if (!map->nt_name) {
			d_printf(_("Out of memory!\n"));
			TALLOC_FREE(map);
			return -1;
		}
	}

	if (grp != NULL)
		map->gid = grp->gr_gid;

	if (!NT_STATUS_IS_OK(pdb_update_group_mapping_entry(map))) {
		d_fprintf(stderr, _("Could not update group mapping for %s\n"),
			  ntgroup);
		TALLOC_FREE(map);
		return -1;
	}

	TALLOC_FREE(map);
	return 0;
}
Пример #28
0
/*******************************************************************
 Process command line options
 ******************************************************************/
static void process_options(int argc, char **argv, BOOL amroot)
{
	int ch;
	DOM_SID dom_sid;
	fstring sid_str;

	user_name[0] = '\0';

	while ((ch = getopt(argc, argv, "c:axdehmnj:t:r:sw:R:D:U:LSW:X:")) != EOF) {
		switch(ch) {
		case 'L':
			local_mode = amroot = True;
			break;
		case 'c':
			pstrcpy(servicesf,optarg);
			break;
		case 'a':
			if (!amroot) goto bad_args;
			local_flags |= LOCAL_ADD_USER;
			break;
		case 'x':
			if (!amroot) goto bad_args;
			local_flags |= LOCAL_DELETE_USER;
			new_passwd = strdup_x("XXXXXX");
			break;
		case 'd':
			if (!amroot) goto bad_args;
			local_flags |= LOCAL_DISABLE_USER;
			new_passwd = strdup_x("XXXXXX");
			break;
		case 'e':
			if (!amroot) goto bad_args;
			local_flags |= LOCAL_ENABLE_USER;
			break;
		case 'm':
			if (!amroot) goto bad_args;
			local_flags |= LOCAL_TRUST_ACCOUNT;
			break;
		case 'n':
			if (!amroot) goto bad_args;
			local_flags |= LOCAL_SET_NO_PASSWORD;
			new_passwd = strdup_x("NO PASSWORD");
			break;
		case 'j':
			if (!amroot) goto bad_args;
			new_domain = optarg;
			strupper(new_domain);
			joining_domain = True;
			break;
                case 't':
                        if (!amroot) goto bad_args;
                        new_domain = optarg;
                        strupper(new_domain);
			changing_trust_pw = True;
                        break;
		case 'r':
			remote_machine = optarg;
			break;
		case 'S': 
			if (!amroot) goto bad_args;
			local_flags |= LOCAL_GET_DOM_SID;
			break;
		case 's':
			set_line_buffering(stdin);
			set_line_buffering(stdout);
			set_line_buffering(stderr);
			stdin_passwd_get = True;
			break;
		case 'w':
			if (!amroot) goto bad_args;
#ifdef WITH_LDAP_SAM
			local_flags |= LOCAL_SET_LDAP_ADMIN_PW;
			fstrcpy(ldap_secret, optarg);
			break;
#else
			printf("-w not available unless configured --with-ldapsam\n");
			goto bad_args;
#endif			
		case 'R':
			if (!amroot) goto bad_args;
			lp_set_name_resolve_order(optarg);
			break;
		case 'D':
			DEBUGLEVEL = atoi(optarg);
			break;
		case 'U': {
			char *lp;

			got_username = True;
			fstrcpy(user_name, optarg);

			if ((lp = strchr(user_name, '%'))) {
				*lp = 0;
				fstrcpy(user_password, lp + 1);
				got_pass = True;
				memset(strchr(optarg, '%') + 1, 'X',
				       strlen(user_password));
			}

		}
		break;

		case 'W': /* Take the SID on the command line and make it ours */
			if (!lp_load(servicesf,True,False,False)) {
				fprintf(stderr, "Can't load %s - run testparm to debug it\n", 
					servicesf);
				exit(1);
			}

			if (!string_to_sid(&dom_sid, optarg)) {
				fprintf(stderr, "Invalid SID: %s\n", optarg);
				exit(1);
			}
		  	if (!secrets_init()) {
				fprintf(stderr, "Unable to open secrets database!\n");
				exit(1);	
		  	}
			if (!secrets_store_domain_sid(global_myname, &dom_sid)) {
				fprintf(stderr, "Unable to write the new SID %s as the server SID for %s\n", optarg, global_myname);
				exit(1);
			}
			/*
			 * Now, write it to the workgroup as well, to make
			 * things consistent. This is a risk however.
			 */
			if (!secrets_store_domain_sid(lp_workgroup(), &dom_sid)) {
				fprintf(stderr, "Unable to write the new SID %s as the domain SID for %s\n", optarg, lp_workgroup());
				exit(1);
			}

	        	exit(0);	
		break;
	
		case 'X': /* Extract the SID for a domain from secrets */
			if (!lp_load(servicesf,True,False,False)) {
				fprintf(stderr, "Can't load %s - run testparm to debug it\n", 
					servicesf);
				exit(1);
			}
		  if (!secrets_init()) {
			fprintf(stderr, "Unable to open secrets database!\n");
			exit(1);
		  }
		  if (secrets_fetch_domain_sid(optarg, &dom_sid)) {
		    sid_to_string(sid_str, &dom_sid);
		    printf("SID for domain %s is: %s\n", optarg, sid_str);
		    exit(0);
		  }
		  else {
		    fprintf(stderr, "Could not retrieve SID for domain: %s\n", optarg);
		    exit(1);
		  }
		  break;
		case 'h':
		default:
bad_args:
			usage();
		}
	}
	
	argc -= optind;
	argv += optind;

	if (joining_domain && (argc != 0))
		usage();

	switch(argc) {
	case 0:
		if (!got_username)
			fstrcpy(user_name, "");
		break;
	case 1:
		if (!amroot == 1) {
			new_passwd = argv[0];
			break;
		}
		if (got_username)
			usage();
		fstrcpy(user_name, argv[0]);
		break;
	case 2:
		if (!amroot || got_username || got_pass)
			usage();
		fstrcpy(user_name, argv[0]);
		new_passwd = strdup_x(argv[1]);
		break;
	default:
		usage();
	}

}
Пример #29
0
static NTSTATUS cmd_lsa_lookup_sids3(struct rpc_pipe_client *cli,
				     TALLOC_CTX *mem_ctx,
				     int argc, const char **argv)
{
	NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
	int i;
	struct lsa_SidArray sids;
	struct lsa_RefDomainList *domains;
	struct lsa_TransNameArray2 names;
	uint32_t count = 0;

	if (argc == 1) {
		printf("Usage: %s [sid1 [sid2 [...]]]\n", argv[0]);
		return NT_STATUS_OK;
	}

	ZERO_STRUCT(names);

	/* Convert arguments to sids */

	sids.num_sids = argc-1;
	sids.sids = talloc_array(mem_ctx, struct lsa_SidPtr, sids.num_sids);
	if (!sids.sids) {
		printf("could not allocate memory for %d sids\n", sids.num_sids);
		goto done;
	}

	for (i = 0; i < sids.num_sids; i++) {
		sids.sids[i].sid = talloc(sids.sids, struct dom_sid);
		if (sids.sids[i].sid == NULL) {
			result = NT_STATUS_NO_MEMORY;
			goto done;
		}
		if (!string_to_sid(sids.sids[i].sid, argv[i+1])) {
			result = NT_STATUS_INVALID_SID;
			goto done;
		}
	}

	/* Lookup the SIDs */
	result = rpccli_lsa_LookupSids3(cli, mem_ctx,
					&sids,
					&domains,
					&names,
					1,
					&count,
					0,
					0);

	if (!NT_STATUS_IS_OK(result) && NT_STATUS_V(result) !=
	    NT_STATUS_V(STATUS_SOME_UNMAPPED))
		goto done;

	result = NT_STATUS_OK;

	/* Print results */

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

		sid_to_fstring(sid_str, sids.sids[i].sid);
		printf("%s %s (%d)\n", sid_str,
		       names.names[i].name.string,
		       names.names[i].sid_type);
	}

 done:
	return result;
}
Пример #30
0
static struct afs_ace *new_afs_ace(TALLOC_CTX *mem_ctx,
				   BOOL positive,
				   const char *name, uint32 rights)
{
	DOM_SID sid;
	enum lsa_SidType type;
	struct afs_ace *result;

	if (strcmp(name, "system:administrators") == 0) {

		sid_copy(&sid, &global_sid_Builtin_Administrators);
		type = SID_NAME_ALIAS;

	} else if (strcmp(name, "system:anyuser") == 0) {

		sid_copy(&sid, &global_sid_World);
		type = SID_NAME_ALIAS;

	} else if (strcmp(name, "system:authuser") == 0) {

		sid_copy(&sid, &global_sid_Authenticated_Users);
		type = SID_NAME_WKN_GRP;

	} else if (strcmp(name, "system:backup") == 0) {

		sid_copy(&sid, &global_sid_Builtin_Backup_Operators);
		type = SID_NAME_ALIAS;

	} else if (sidpts) {
		/* All PTS users/groups are expressed as SIDs */

		sid_copy(&sid, &global_sid_NULL);
		type = SID_NAME_UNKNOWN;

		if (string_to_sid(&sid, name)) {
			const char *user, *domain;
			/* We have to find the type, look up the SID */
			lookup_sid(tmp_talloc_ctx(), &sid,
				   &domain, &user, &type);
		}

	} else {

		const char *domain, *uname;
		char *p;

		p = strchr_m(name, *lp_winbind_separator());
		if (p != NULL) {
			*p = '\\';
		}

		if (!lookup_name(tmp_talloc_ctx(), name, LOOKUP_NAME_ALL,
				 &domain, &uname, &sid, &type)) {
			DEBUG(10, ("Could not find AFS user %s\n", name));

			sid_copy(&sid, &global_sid_NULL);
			type = SID_NAME_UNKNOWN;

		}
	}

	result = TALLOC_P(mem_ctx, struct afs_ace);

	if (result == NULL) {
		DEBUG(0, ("Could not talloc AFS ace\n"));
		return NULL;
	}

	result->name = talloc_strdup(mem_ctx, name);
	if (result->name == NULL) {
		DEBUG(0, ("Could not talloc AFS ace name\n"));
		return NULL;
	}

	result->sid = sid;
	result->type = type;

	result->positive = positive;
	result->rights = rights;

	return result;
}