Exemple #1
0
int
usersFileRead(char* path)
{
	char *p;
	File *file;
	Fsys *fsys;
	int len, r;
	uvlong size;

	if((fsys = fsysGet("main")) == nil)
		return 0;
	fsysFsRlock(fsys);

	if(path == nil)
		path = "/active/adm/users";

	r = 0;
	if((file = fileOpen(fsysGetFs(fsys), path)) != nil){
		if(fileGetSize(file, &size)){
			len = size;
			p = vtMemAlloc(size+1);
			if(fileRead(file, p, len, 0) == len){
				p[len] = '\0';
				r = uboxInit(p, len);
			}
		}
		fileDecRef(file);
	}

	fsysFsRUnlock(fsys);
	fsysPut(fsys);

	return r;
}
Exemple #2
0
int
fileMetaFlush(File *f, int rec)
{
	File **kids, *p;
	int nkids;
	int i, rv;

	fileMetaLock(f);
	rv = fileMetaFlush2(f, nil);
	fileMetaUnlock(f);

	if(!rec || !fileIsDir(f))
		return rv;

	if(!fileLock(f))
		return rv;
	nkids = 0;
	for(p=f->down; p; p=p->next)
		nkids++;
	kids = vtMemAlloc(nkids*sizeof(File*));
	i = 0;
	for(p=f->down; p; p=p->next){
		kids[i++] = p;
		p->ref++;
	}
	fileUnlock(f);

	for(i=0; i<nkids; i++){
		rv |= fileMetaFlush(kids[i], 1);
		fileDecRef(kids[i]);
	}
	vtMemFree(kids);
	return rv;
}
Exemple #3
0
void *
vtMemAllocZ(int size)
{
	void *p = vtMemAlloc(size);
	memset(p, 0, size);
	setmalloctag(p, getcallerpc(&size));
	return p;
}
Exemple #4
0
VtSha1 *
vtSha1Alloc(void)
{
	VtSha1 *s;

	s = vtMemAlloc(sizeof(VtSha1));
	vtSha1Init(s);
	return s;
}
Exemple #5
0
static uchar*
copyBlock(Block *b, u32int blockSize)
{
	uchar *data;

	data = vtMemAlloc(blockSize);
	if(data == nil)
		return nil;
	memmove(data, b->data, blockSize);
	return data;
}
Exemple #6
0
void *
vtMemRealloc(void *p, int size)
{
	if(p == nil)
		return vtMemAlloc(size);
	p = realloc(p, size);
	if(p == 0)
		vtFatal("vtRealloc: out of memory");
	setrealloctag(p, getcallerpc(&size));
	return p;
}
Exemple #7
0
static int
deeFill(DirEntryEnum *dee)
{
	int i, n;
	Source *meta, *source;
	MetaBlock mb;
	MetaEntry me;
	File *f;
	Block *b;
	DirEntry *de;

	/* clean up first */
	for(i=dee->i; i<dee->n; i++)
		deCleanup(dee->buf+i);
	vtMemFree(dee->buf);
	dee->buf = nil;
	dee->i = 0;
	dee->n = 0;

	f = dee->file;

	source = f->source;
	meta = f->msource;

	b = sourceBlock(meta, dee->boff, OReadOnly);
	if(b == nil)
		goto Err;
	if(!mbUnpack(&mb, b->data, meta->dsize))
		goto Err;

	n = mb.nindex;
	dee->buf = vtMemAlloc(n * sizeof(DirEntry));

	for(i=0; i<n; i++){
		de = dee->buf + i;
		meUnpack(&me, &mb, i);
		if(!deUnpack(de, &me))
			goto Err;
		dee->n++;
		if(!(de->mode & ModeDir))
		if(!dirEntrySize(source, de->entry, de->gen, &de->size))
			goto Err;
	}
	dee->boff++;
	blockPut(b);
	return 1;
Err:
	blockPut(b);
	return 0;
}
Exemple #8
0
/*
 * Fsck that MetaBlock has reasonable header, sorted entries,
 */
static int
chkMetaBlock(MetaBlock *mb)
{
	MetaChunk *mc;
	int oo, o, n, i;
	uchar *p;

	mc = vtMemAlloc(mb->nindex*sizeof(MetaChunk));
	p = mb->buf + MetaHeaderSize;
	for(i = 0; i < mb->nindex; i++){
		mc[i].offset = p[0]<<8 | p[1];
		mc[i].size =   p[2]<<8 | p[3];
		mc[i].index = i;
		p += MetaIndexSize;
	}

	qsort(mc, mb->nindex, sizeof(MetaChunk), offsetCmp);

	/* check block looks ok */
	oo = MetaHeaderSize + mb->maxindex*MetaIndexSize;
	o = oo;
	n = 0;
	for(i = 0; i < mb->nindex; i++){
		o = mc[i].offset;
		n = mc[i].size;
		if(o < oo)
			goto Err;
		oo += n;
	}
	if(o+n > mb->size || mb->size - oo != mb->free)
		goto Err;

	vtMemFree(mc);
	return 1;

Err:
if(0){
	fprint(2, "metaChunks failed!\n");
	oo = MetaHeaderSize + mb->maxindex*MetaIndexSize;
	for(i=0; i<mb->nindex; i++){
		fprint(2, "\t%d: %d %d\n", i, mc[i].offset,
			mc[i].offset + mc[i].size);
		oo += mc[i].size;
	}
	fprint(2, "\tused=%d size=%d free=%d free2=%d\n",
		oo, mb->size, mb->free, mb->size - oo);
}
	vtMemFree(mc);
	return 0;
}
Exemple #9
0
static MetaChunk *
metaChunks(MetaBlock *mb)
{
	MetaChunk *mc;
	int oo, o, n, i;
	uchar *p;

	mc = vtMemAlloc(mb->nindex*sizeof(MetaChunk));
	p = mb->buf + MetaHeaderSize;
	for(i = 0; i<mb->nindex; i++){
		mc[i].offset = U16GET(p);
		mc[i].size = U16GET(p+2);
		mc[i].index = i;
		p += MetaIndexSize;
	}

	qsort(mc, mb->nindex, sizeof(MetaChunk), offsetCmp);

	/* check block looks ok */
	oo = MetaHeaderSize + mb->maxindex*MetaIndexSize;
	o = oo;
	n = 0;
	for(i=0; i<mb->nindex; i++){
		o = mc[i].offset;
		n = mc[i].size;
		if(o < oo)
			goto Err;
		oo += n;
	}
	if(o+n > mb->size)
		goto Err;
	if(mb->size - oo != mb->free)
		goto Err;

	return mc;
Err:
fprint(2, "metaChunks failed!\n");
oo = MetaHeaderSize + mb->maxindex*MetaIndexSize;
for(i=0; i<mb->nindex; i++){
fprint(2, "\t%d: %d %d\n", i, mc[i].offset, mc[i].offset + mc[i].size);
oo += mc[i].size;
}
fprint(2, "\tused=%d size=%d free=%d free2=%d\n", oo, mb->size, mb->free, mb->size - oo);
	vtSetError(EBadMeta);
	vtMemFree(mc);
	return nil;
}
Exemple #10
0
static int
stringUnpack(char **s, uchar **p, int *n)
{
	int nn;

	if(*n < 2)
		return 0;

	nn = U16GET(*p);
	*p += 2;
	*n -= 2;
	if(nn > *n)
		return 0;
	*s = vtMemAlloc(nn+1);
	memmove(*s, *p, nn);
	(*s)[nn] = 0;
	*p += nn;
	*n -= nn;
	return 1;
}
Exemple #11
0
int
vtGetString(Packet *p, char **ret)
{
	uint8_t buf[2];
	int n;
	char *s;

	if(!packetConsume(p, buf, 2))
		return 0;
	n = (buf[0]<<8) + buf[1];
	if(n > VtMaxStringSize) {
		vtSetError(EBigString);
		return 0;
	}
	s = vtMemAlloc(n+1);
	setmalloctag(s, getcallerpc());
	if(!packetConsume(p, (uint8_t*)s, n)) {
		vtMemFree(s);
		return 0;
	}
	s[n] = 0;
	*ret = s;
	return 1;
}
Exemple #12
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;
}
Exemple #13
0
static int
usersFileWrite(Ubox* box)
{
	Fs *fs;
	User *u;
	int i, r;
	Fsys *fsys;
	char *p, *q, *s;
	File *dir, *file;

	if((fsys = fsysGet("main")) == nil)
		return 0;
	fsysFsRlock(fsys);
	fs = fsysGetFs(fsys);

	/*
	 * BUG:
	 * 	the owner/group/permissions need to be thought out.
	 */
	r = 0;
	if((dir = fileOpen(fs, "/active")) == nil)
		goto tidy0;
	if((file = fileWalk(dir, uidadm)) == nil)
		file = fileCreate(dir, uidadm, ModeDir|0775, uidadm);
	fileDecRef(dir);
	if(file == nil)
		goto tidy;
	dir = file;
	if((file = fileWalk(dir, "users")) == nil)
		file = fileCreate(dir, "users", 0664, uidadm);
	fileDecRef(dir);
	if(file == nil)
		goto tidy;
	if(!fileTruncate(file, uidadm))
		goto tidy;

	p = s = vtMemAlloc(box->len+1);
	q = p + box->len+1;
	for(u = box->head; u != nil; u = u->next){
		p += snprint(p, q-p, "%s:%s:", u->uid, u->uname);
		if(u->leader != nil)
			p+= snprint(p, q-p, u->leader);
		p += snprint(p, q-p, ":");
		if(u->ngroup){
			p += snprint(p, q-p, u->group[0]);
			for(i = 1; i < u->ngroup; i++)
				p += snprint(p, q-p, ",%s", u->group[i]);
		}
		p += snprint(p, q-p, "\n");
	}
	r = fileWrite(file, s, box->len, 0, uidadm);
	vtMemFree(s);

tidy:
	if(file != nil)
		fileDecRef(file);
tidy0:
	fsysFsRUnlock(fsys);
	fsysPut(fsys);

	return r;
}