void *alignedMalloc(size_t size, size_t align)
{
	void *mem = userAlloc(size + (align-1) + sizeof(void*));

	char *amem = ((char*)mem) + sizeof(void*);
	if( (uintptr_t)amem & (align - 1) )
		amem += align - ((uintptr_t)amem & (align - 1));

	((void**)amem)[-1] = mem;
	return amem;
}
Exemple #2
0
static int
cmdUname(int argc, char* argv[])
{
	User *u, *up;
	int d, dflag, i, r;
	char *p, *uid, *uname;
	char *createfmt = "fsys main create /active/usr/%s %s %s d775";
	char *usage = "usage: uname [-d] uname [uid|:uid|%%newname|=leader|+member|-member]";

	dflag = 0;

	ARGBEGIN{
	default:
		return cliError(usage);
	case 'd':
		dflag = 1;
		break;
	}ARGEND

	if(argc < 1){
		if(!dflag)
			return cliError(usage);
		vtRLock(ubox.lock);
		uboxDump(ubox.box);
		vtRUnlock(ubox.lock);
		return 1;
	}

	uname = argv[0];
	argc--; argv++;

	if(argc == 0){
		vtRLock(ubox.lock);
		if((u = _userByUname(ubox.box, uname)) == nil){
			vtRUnlock(ubox.lock);
			return 0;
		}
		consPrint("\t%U\n", u);
		vtRUnlock(ubox.lock);
		return 1;
	}

	vtLock(ubox.lock);
	u = _userByUname(ubox.box, uname);
	while(argc--){
		if(argv[0][0] == '%'){
			if(u == nil){
				vtUnlock(ubox.lock);
				return 0;
			}
			p = &argv[0][1];
			if((up = _userByUname(ubox.box, p)) != nil){
				vtSetError("uname: uname '%s' already exists",
					up->uname);
				vtUnlock(ubox.lock);
				return 0;
			}
			for(i = 0; usersMandatory[i] != nil; i++){
				if(strcmp(usersMandatory[i], uname) != 0)
					continue;
				vtSetError("uname: uname '%s' is mandatory",
					uname);
				vtUnlock(ubox.lock);
				return 0;
			}

			d = strlen(p) - strlen(u->uname);
			for(up = ubox.box->head; up != nil; up = up->next){
				if(up->leader != nil){
					if(strcmp(up->leader, u->uname) == 0){
						vtMemFree(up->leader);
						up->leader = vtStrDup(p);
						ubox.box->len += d;
					}
				}
				for(i = 0; i < up->ngroup; i++){
					if(strcmp(up->group[i], u->uname) != 0)
						continue;
					vtMemFree(up->group[i]);
					up->group[i] = vtStrDup(p);
					ubox.box->len += d;
					break;
				}
			}

			uboxRemUser(ubox.box, u);
			vtMemFree(u->uname);
			u->uname = vtStrDup(p);
			uboxAddUser(ubox.box, u);
		}
		else if(argv[0][0] == '='){
			if(u == nil){
				vtUnlock(ubox.lock);
				return 0;
			}
			if((up = _userByUname(ubox.box, &argv[0][1])) == nil){
				if(argv[0][1] != '\0'){
					vtUnlock(ubox.lock);
					return 0;
				}
			}
			if(u->leader != nil){
				ubox.box->len -= strlen(u->leader);
				vtMemFree(u->leader);
				u->leader = nil;
			}
			if(up != nil){
				u->leader = vtStrDup(up->uname);
				ubox.box->len += strlen(u->leader);
			}
		}
		else if(argv[0][0] == '+'){
			if(u == nil){
				vtUnlock(ubox.lock);
				return 0;
			}
			if((up = _userByUname(ubox.box, &argv[0][1])) == nil){
				vtUnlock(ubox.lock);
				return 0;
			}
			if(!_groupAddMember(ubox.box, u, up->uname)){
				vtUnlock(ubox.lock);
				return 0;
			}
		}
		else if(argv[0][0] == '-'){
			if(u == nil){
				vtUnlock(ubox.lock);
				return 0;
			}
			if((up = _userByUname(ubox.box, &argv[0][1])) == nil){
				vtUnlock(ubox.lock);
				return 0;
			}
			if(!_groupRemMember(ubox.box, u, up->uname)){
				vtUnlock(ubox.lock);
				return 0;
			}
		}
		else{
			if(u != nil){
				vtSetError("uname: uname '%s' already exists",
					u->uname);
				vtUnlock(ubox.lock);
				return 0;
			}

			uid = argv[0];
			if(*uid == ':')
				uid++;
			if((u = _userByUid(ubox.box, uid)) != nil){
				vtSetError("uname: uid '%s' already exists",
					u->uid);
				vtUnlock(ubox.lock);
				return 0;
			}

			u = userAlloc(uid, uname);
			uboxAddUser(ubox.box, u);
			if(argv[0][0] != ':'){
				// should have an option for the mode and gid
				p = smprint(createfmt, uname, uname, uname);
				r = cliExec(p);
				vtMemFree(p);
				if(r == 0){
					vtUnlock(ubox.lock);
					return 0;
				}
			}
		}
		argv++;
	}

	if(usersFileWrite(ubox.box) == 0){
		vtUnlock(ubox.lock);
		return 0;
	}
	if(dflag)
		uboxDump(ubox.box);
	vtUnlock(ubox.lock);

	return 1;
}
Exemple #3
0
static int
uboxInit(char* users, int len)
{
	User *g, *u;
	Ubox *box, *obox;
	int blank, comment, i, nline, nuser;
	char *buf, *f[5], **line, *p, *q, *s;

	/*
	 * Strip out whitespace and comments.
	 * Note that comments are pointless, they disappear
	 * when the server writes the database back out.
	 */
	blank = 1;
	comment = nline = 0;

	s = p = buf = vtMemAlloc(len+1);
	for(q = users; *q != '\0'; q++){
		if(*q == '\r' || *q == '\t' || *q == ' ')
			continue;
		if(*q == '\n'){
			if(!blank){
				if(p != s){
					*p++ = '\n';
					nline++;
					s = p;
				}
				blank = 1;
			}
			comment = 0;
			continue;
		}
		if(*q == '#')
			comment = 1;
		blank = 0;
		if(!comment)
			*p++ = *q;
	}
	*p = '\0';

	line = vtMemAllocZ((nline+2)*sizeof(char*));
	if((i = gettokens(buf, line, nline+2, "\n")) != nline){
		fprint(2, "nline %d (%d) botch\n", nline, i);
		vtMemFree(line);
		vtMemFree(buf);
		return 0;
	}

	/*
	 * Everything is updated in a local Ubox until verified.
	 */
	box = vtMemAllocZ(sizeof(Ubox));

	/*
	 * First pass - check format, check for duplicates
	 * and enter in hash buckets.
	 */
	nuser = 0;
	for(i = 0; i < nline; i++){
		s = vtStrDup(line[i]);
		if(getfields(s, f, nelem(f), 0, ":") != 4){
			fprint(2, "bad line '%s'\n", line[i]);
			vtMemFree(s);
			continue;
		}
		if(*f[0] == '\0' || *f[1] == '\0'){
			fprint(2, "bad line '%s'\n", line[i]);
			vtMemFree(s);
			continue;
		}
		if(!validUserName(f[0])){
			fprint(2, "invalid uid '%s'\n", f[0]);
			vtMemFree(s);
			continue;
		}
		if(_userByUid(box, f[0]) != nil){
			fprint(2, "duplicate uid '%s'\n", f[0]);
			vtMemFree(s);
			continue;
		}
		if(!validUserName(f[1])){
			fprint(2, "invalid uname '%s'\n", f[0]);
			vtMemFree(s);
			continue;
		}
		if(_userByUname(box, f[1]) != nil){
			fprint(2, "duplicate uname '%s'\n", f[1]);
			vtMemFree(s);
			continue;
		}

		u = userAlloc(f[0], f[1]);
		uboxAddUser(box, u);
		line[nuser] = line[i];
		nuser++;

		vtMemFree(s);
	}
	assert(box->nuser == nuser);

	/*
	 * Second pass - fill in leader and group information.
	 */
	for(i = 0; i < nuser; i++){
		s = vtStrDup(line[i]);
		getfields(s, f, nelem(f), 0, ":");

		assert(g = _userByUname(box, f[1]));
		if(*f[2] != '\0'){
			if((u = _userByUname(box, f[2])) == nil)
				g->leader = vtStrDup(g->uname);
			else
				g->leader = vtStrDup(u->uname);
			box->len += strlen(g->leader);
		}
		for(p = f[3]; p != nil; p = q){
			if((q = utfrune(p, L',')) != nil)
				*q++ = '\0';
			if(!_groupAddMember(box, g, p)){
				// print/log error here
			}
		}

		vtMemFree(s);
	}

	vtMemFree(line);
	vtMemFree(buf);

	for(i = 0; usersMandatory[i] != nil; i++){
		if((u = _userByUid(box, usersMandatory[i])) == nil){
			vtSetError("user '%s' is mandatory", usersMandatory[i]);
			uboxFree(box);
			return 0;
		}
		if(strcmp(u->uid, u->uname) != 0){
			vtSetError("uid/uname for user '%s' must match",
				usersMandatory[i]);
			uboxFree(box);
			return 0;
		}
	}

	vtLock(ubox.lock);
	obox = ubox.box;
	ubox.box = box;
	vtUnlock(ubox.lock);

	if(obox != nil)
		uboxFree(obox);

	return 1;
}