]> andersk Git - moira.git/blame - afssync/ptutils.c
punt UBIK version number checking; Write UBIK header when creating
[moira.git] / afssync / ptutils.c
CommitLineData
e1f001e5 1/* $Header$ */
2/* $Source$ */
3
4
5/*
6 * P_R_P_Q_# (C) COPYRIGHT IBM CORPORATION 1988
7 * LICENSED MATERIALS - PROPERTY OF IBM
8 * REFER TO COPYRIGHT INSTRUCTIONS FORM NUMBER G120-2083
9 */
10
11/*
12 Sherri Nichols
13 Information Technology Center
14 November, 1988
15
16 Modified May, 1989 by Jeff Schiller to keep disk file in
17 network byte order
18
19*/
20
21#include <stdio.h>
22#include <strings.h>
23#include <lock.h>
0c4439d6 24#define UBIK_INTERNALS
e1f001e5 25#include <ubik.h>
26#include <rx/xdr.h>
27#include "print.h"
28#include "prserver.h"
29#include "prerror.h"
30#include <netinet/in.h>
31
32extern struct prheader cheader;
33extern struct ubik_dbase *dbase;
34extern struct afsconf_dir *prdir;
35
36long CreateEntry(at, aname, aid, idflag,flag,oid,creator)
37register struct ubik_trans *at;
38char aname[PR_MAXNAMELEN];
39long *aid;
40long idflag;
41long flag;
42long oid;
43long creator;
44{
45 /* get and init a new entry */
46 register long code;
47 long newEntry;
48 long temp;
49 struct prentry tentry;
50
51 bzero(&tentry, sizeof(tentry));
52 newEntry = AllocBlock(at);
53 if (!newEntry) return PRDBFAIL;
54 if (flag & PRGRP) {
55 tentry.flags |= PRGRP;
56 tentry.owner = oid;
57 }
58 else if (flag & PRFOREIGN) {
59 tentry.flags |= PRFOREIGN;
60 tentry.owner = oid;
61 }
62 else tentry.owner = SYSADMINID;
63 if (idflag)
64 tentry.id = *aid;
65 else {
66 code= AllocID(at,flag,&tentry.id);
67 if (code != PRSUCCESS) return code;
68 }
69 if (flag & PRGRP) {
70 if (tentry.id < ntohl(cheader.maxGroup)) {
71 cheader.maxGroup = htonl(tentry.id);
72 code = pr_Write(at,0,16,(char *) &cheader.maxGroup,sizeof(cheader.maxGroup));
73 if (code) return PRDBFAIL;
74 }
75 }
76 else if (flag & PRFOREIGN) {
77 if (tentry.id > ntohl(cheader.maxForeign)) {
78 cheader.maxForeign = htonl(tentry.id);
79 code = pr_Write(at,0,24,(char *) &cheader.maxForeign,sizeof(cheader.maxForeign));
80 if (code) return PRDBFAIL;
81 }
82 }
83 else {
84 if (tentry.id > ntohl(cheader.maxID)) {
85 cheader.maxID = htonl(tentry.id);
86 code = pr_Write(at,0,20,(char *) &cheader.maxID,sizeof(cheader.maxID));
87 if (code) return PRDBFAIL;
88 }
89 }
90 tentry.creator = creator;
91 *aid = tentry.id;
92 strncpy(tentry.name, aname, PR_MAXNAMELEN);
93 code = pr_WriteEntry(at, 0, newEntry, &tentry);
94 if (code) return PRDBFAIL;
95 code = AddToIDHash(at,*aid,newEntry);
96 if (code != PRSUCCESS) return code;
97 code = AddToNameHash(at,aname,newEntry);
98 if (code != PRSUCCESS) return code;
99 if (tentry.flags & PRGRP) {
100 code = AddToOwnerChain(at,tentry.id,oid);
101 if (code) return code;
102 }
103 if (tentry.flags & PRGRP) {
104 temp = ntohl(cheader.groupcount) + 1;
105 cheader.groupcount = htonl(temp);
106 code = pr_Write(at,0,40,(char *)&cheader.groupcount,sizeof(cheader.groupcount));
107 if (code) return PRDBFAIL;
108 }
109 else if (tentry.flags & PRFOREIGN) {
110 temp = ntohl(cheader.foreigncount) + 1;
111 cheader.foreigncount = htonl(temp);
112 code = pr_Write(at,0,44,(char *)&cheader.foreigncount,sizeof(cheader.foreigncount));
113 if (code) return PRDBFAIL;
114 }
115 else if (tentry.flags & PRINST) {
116 temp = ntohl(cheader.instcount) + 1;
117 cheader.instcount = htonl(temp);
118 code = pr_Write(at,0,48,(char *)&cheader.instcount,sizeof(cheader.instcount));
119 if (code) return PRDBFAIL;
120 }
121 else {
122 temp = ntohl(cheader.usercount) + 1;
123 cheader.usercount = htonl(temp);
124 code = pr_Write(at,0,36,(char *)&cheader.usercount,sizeof(cheader.usercount));
125 if (code) return PRDBFAIL;
126 }
127 return PRSUCCESS;
128}
129
130
131
132long RemoveFromEntry(at,aid,bid)
133register struct ubik_trans *at;
134register long aid;
135register long bid;
136{
137 /* remove aid from bid's entries list, freeing a continuation entry if appropriate */
138
139 register long code;
140 struct prentry tentry;
141 struct contentry centry;
142 struct contentry hentry;
143 long temp;
144 long first;
145 long i,j;
146 long nptr;
147 long hloc = 0;
148
149 bzero(&hentry,sizeof(hentry));
150 temp = FindByID(at,bid);
151 code = pr_ReadEntry(at, 0, temp, &tentry);
152 if (code != 0) return code;
153 for (i=0;i<PRSIZE;i++) {
154 if (tentry.entries[i] == aid) {
155 tentry.entries[i] = PRBADID;
156 tentry.count--;
157 code = pr_WriteEntry(at,0,temp,&tentry);
158 if (code != 0) return code;
159 return PRSUCCESS;
160 }
161 if (tentry.entries[i] == 0) /* found end of list */
162 return PRNOENT;
163 }
164 if (tentry.next != NULL) {
165 nptr = tentry.next;
166 first = 1;
167 while (nptr != NULL) {
168 code = pr_ReadCoEntry(at,0,nptr,&centry);
169 if (code != 0) return code;
170 for (i=0;i<COSIZE;i++) {
171 if (centry.entries[i] == aid) {
172 centry.entries[i] = PRBADID;
173 tentry.count--;
174 code = pr_WriteEntry(at,0,temp,&tentry);
175 if (code) return PRDBFAIL;
176 for (j=0;j<COSIZE;j++)
177 if (centry.entries[j] != PRBADID && centry.entries[j] != 0) break;
178 if (j == COSIZE) { /* can free this block */
179 if (first) {
180 tentry.next = centry.next;
181 code = pr_WriteEntry(at,0,temp,&tentry);
182 if (code != 0) return code;
183 }
184 else {
185 hentry.next = centry.next;
186 code = pr_WriteCoEntry(at,0,hloc,(char *) &hentry);
187 if (code != 0) return code;
188 }
189 code = FreeBlock(at,nptr);
190 return code;
191 }
192 else { /* can't free it yet */
193 code = pr_WriteCoEntry(at,0,nptr,&centry);
194 if (code != 0) return code;
195 return PRSUCCESS;
196 }
197 }
198 if (centry.entries[i] == 0) return PRNOENT;
199 }
200 hloc = nptr;
201 nptr = centry.next;
202 bcopy(&centry,&hentry,sizeof(centry));
203 }
204 }
205 else return PRNOENT;
206 return PRSUCCESS;
207}
208
209long DeleteEntry(at,aid,cid)
210register struct ubik_trans *at;
211long aid;
212long cid;
213{
214 /* delete the entry aid, removing it from all groups, putting groups owned by it on orphan chain, and freeing the space */
215 register long code;
216 long temp;
217 long temp1;
218 struct prentry tentry;
219 struct contentry centry;
220 struct prentry nentry;
221 register long i;
222 long nptr;
223 long noAuth;
224
225 noAuth = afsconf_GetNoAuthFlag(prdir);
226 bzero(&tentry,sizeof(tentry));
227 temp = FindByID(at,aid);
228 if (!temp) return PRNOENT;
229 code = pr_ReadEntry(at,0,temp,&tentry);
230 if (code != 0) return PRDBFAIL;
231 if (tentry.owner != cid && !IsAMemberOf(at,cid,SYSADMINID) && !IsAMemberOf(at,cid,tentry.owner) && !noAuth) return PRPERM;
232 for (i=0;i<PRSIZE;i++) {
233 if (tentry.entries[i] == 0) break;
234 RemoveFromEntry(at,aid,tentry.entries[i]);
235 }
236 nptr = tentry.next;
237 while (nptr != NULL) {
238 code = pr_ReadCoEntry(at,0,nptr,&centry);
239 if (code != 0) return PRDBFAIL;
240 for (i=0;i<COSIZE;i++) {
241 if (centry.entries[i] == 0) break;
242 RemoveFromEntry(at,aid,centry.entries[i]);
243 }
244 nptr = centry.next;
245 }
246 if (tentry.flags & PRGRP) {
247 if (FindByID(at,tentry.owner)) {
248 code = RemoveFromOwnerChain(at,aid,tentry.owner);
249 if (code) return code;
250 }
251 else {
252 code = RemoveFromOrphan(at,aid);
253 if (code) return code;
254 }
255 }
256 if (tentry.owned) {
257 nptr = tentry.owned;
258 while (nptr != NULL) {
259 code = pr_ReadEntry(at,0,nptr,&nentry);
260 if (code != 0) return PRDBFAIL;
261 if (nentry.id != aid) /* don't add this entry to orphan chain! */
262 code = AddToOrphan(at,nentry.id);
263 nptr = nentry.nextOwned;
264 }
265 }
266 code = RemoveFromIDHash(at,tentry.id,&temp);
267 if (code != PRSUCCESS) return code;
268 code = RemoveFromNameHash(at,tentry.name,&temp);
269 if (code != PRSUCCESS) return code;
270 if (tentry.flags & PRGRP) {
271 temp1 = ntohl(cheader.groupcount) + 1;
272 cheader.groupcount = htonl(temp1);
273 code = pr_Write(at,0,40,(char *)&cheader.groupcount,sizeof(cheader.groupcount));
274 if (code) return PRDBFAIL;
275 }
276 else if (tentry.flags & PRFOREIGN) {
277 temp1 = ntohl(cheader.foreigncount) + 1;
278 cheader.foreigncount = htonl(temp1);
279 code = pr_Write(at,0,44,(char *)&cheader.foreigncount,sizeof(cheader.foreigncount));
280 if (code) return PRDBFAIL;
281 }
282 else if (tentry.flags & PRINST) {
283 temp1 = ntohl(cheader.instcount) + 1;
284 cheader.instcount = htonl(temp1);
285 code = pr_Write(at,0,48,(char *)&cheader.instcount,sizeof(cheader.instcount));
286 if (code) return PRDBFAIL;
287 }
288 else {
289 temp1 = ntohl(cheader.usercount) + 1;
290 cheader.usercount = htonl(temp1);
291 code = pr_Write(at,0,36,(char *)&cheader.usercount,sizeof(cheader.usercount));
292 if (code) return PRDBFAIL;
293 }
294 FreeBlock(at,temp);
295 return PRSUCCESS;
296}
297
298
299
300
301long AddToEntry(tt,entry,loc,aid)
302struct ubik_trans *tt;
303struct prentry entry;
304long loc;
305long aid;
306{
307 /* add aid to entry's entries list, alloc'ing a continuation block if needed */
308 register long code;
309 long i;
310 struct contentry nentry;
311 struct contentry aentry;
312 long nptr;
313 long last = 0;
314 long first = 0;
315 long cloc;
316 long slot = -1;
317
318 bzero(&nentry,sizeof(nentry));
319 bzero(&aentry,sizeof(aentry));
320 for (i=0;i<PRSIZE;i++) {
321 if (entry.entries[i] == aid)
322 return PRIDEXIST;
323 if (entry.entries[i] == PRBADID) { /* remember this spot */
324 first = 1;
325 slot = i;
326 }
327 if (entry.entries[i] == 0) { /* end of the line */
328 if (slot == -1) {
329 first = 1;
330 slot = i;
331 }
332 break;
333 }
334 }
335 nptr = entry.next;
336 while (nptr != NULL) {
337 code = pr_ReadCoEntry(tt,0,nptr,&nentry);
338 if (code != 0) return code;
339 if (!(nentry.flags & PRCONT)) return PRDBFAIL;
340 for (i=0;i<COSIZE;i++) {
341 if (nentry.entries[i] == aid)
342 return PRIDEXIST;
343 if (nentry.entries[i] == PRBADID) {
344 if (slot == -1) {
345 slot = i;
346 cloc = nptr;
347 }
348 }
349 if (nentry.entries[i] == 0) {
350 if (slot == -1) {
351 slot = i;
352 cloc = nptr;
353 }
354 break;
355 }
356 }
357 last = nptr;
358 nptr = nentry.next;
359 }
360 if (slot != -1) { /* we found a place */
361 entry.count++;
362 if (first) { /* place is in first block */
363 entry.entries[slot] = aid;
364 code = pr_WriteEntry(tt,0,loc,&entry);
365 if (code != 0) return code;
366 return PRSUCCESS;
367 }
368 code = pr_WriteEntry(tt,0,loc,&entry);
369 code = pr_ReadCoEntry(tt,0,cloc,&aentry);
370 if (code != 0) return code;
371 aentry.entries[slot] = aid;
372 code = pr_WriteCoEntry(tt,0,cloc,&aentry);
373 if (code != 0) return code;
374 return PRSUCCESS;
375 }
376 /* have to allocate a continuation block if we got here */
377 nptr = AllocBlock(tt);
378 if (nentry.flags & PRCONT) {
379 /* then we should tack new block here */
380 nentry.next = nptr;
381 code = pr_WriteCoEntry(tt,0,last,&nentry);
382 if (code != 0) return code;
383 }
384 else {
385 entry.next = nptr;
386 code = pr_WriteEntry(tt,0,loc,&entry);
387 if (code != 0) return code;
388 }
389 aentry.flags |= PRCONT;
390 aentry.id = entry.id;
391 aentry.next = NULL;
392 aentry.entries[0] = aid;
393 code = pr_WriteCoEntry(tt,0,nptr,&aentry);
394 if (code != 0) return code;
395 /* don't forget to update count, here! */
396 entry.count++;
397 code = pr_WriteEntry(tt,0,loc,&entry);
398 return PRSUCCESS;
399
400}
401
402long GetList(at,aid,alist,add)
403struct ubik_trans *at;
404long aid;
405prlist *alist;
406long add;
407{
408 register long code;
409 long temp;
410 long i;
411 long count;
412 struct prentry tentry;
413 struct contentry centry;
414 long nptr;
415 long size;
416 extern long IDCmp();
417
418 temp = FindByID(at,aid);
419 if (!temp) return PRNOENT;
420 code = pr_ReadEntry(at,0,temp,&tentry);
421 if (code != 0) return code;
422 alist->prlist_val = (long *)malloc(100*sizeof(long));
423 size = 100;
424 alist->prlist_len = 0;
425 count = 0;
426 for (i=0;i<PRSIZE;i++) {
427 if (tentry.entries[i] == PRBADID) continue;
428 if (tentry.entries[i] == 0) break;
429 alist->prlist_val[count]= tentry.entries[i];
430 count++;
431 alist->prlist_len++;
432 }
433 nptr = tentry.next;
434 while (nptr != NULL) {
435 /* look through cont entries */
436 code = pr_ReadCoEntry(at,0,nptr,&centry);
437 if (code != 0) return code;
438 for (i=0;i<COSIZE;i++) {
439 if (centry.entries[i] == PRBADID) continue;
440 if (centry.entries[i] == 0) break;
441 if (alist->prlist_len >= size) {
442 alist->prlist_val = (long *)realloc(alist->prlist_val,(size+100)*sizeof(long));
443 size += 100;
444 }
445 alist->prlist_val[count] = centry.entries[i];
446 count++;
447 alist->prlist_len++;
448 }
449 nptr = centry.next;
450 }
451 if (add) { /* this is for a CPS, so tack on appropriate stuff */
452 if (aid != ANONYMOUSID && aid != ANYUSERID) {
453 if (alist->prlist_len >= size)
454 alist->prlist_val = (long *)realloc(alist->prlist_val,(size + 3)*sizeof(long));
455 alist->prlist_val[count] = ANYUSERID;
456 count++;
457 alist->prlist_val[count] = AUTHUSERID;
458 count++;
459 alist->prlist_val[count] = aid;
460 count++;
461 alist->prlist_len += 3;
462 }
463 else {
464 if (alist->prlist_len >= size)
465 alist->prlist_val = (long *)realloc(alist->prlist_val,(size + 2)*sizeof(long));
466 alist->prlist_val[count] = ANYUSERID;
467 count++;
468 alist->prlist_val[count] = aid;
469 count++;
470 alist->prlist_len += 2;
471 }
472 }
473 qsort(alist->prlist_val,alist->prlist_len,sizeof(long),IDCmp);
474 return PRSUCCESS;
475}
476
477long GetMax(at,uid,gid)
478register struct ubik_trans *at;
479long *uid;
480long *gid;
481{
482 *uid = ntohl(cheader.maxID);
483 *gid = ntohl(cheader.maxGroup);
484 return PRSUCCESS;
485}
486
487long SetMax(at,id,flag)
488register struct ubik_trans *at;
489long id;
490long flag;
491{
492 register long code;
493 if (flag & PRGRP) {
494 cheader.maxGroup = htonl(id);
495 code = pr_Write(at,0,16,(char *)&cheader.maxGroup,sizeof(cheader.maxGroup));
496 if (code != 0) return code;
497 }
498 else {
499 cheader.maxID = htonl(id);
500 code = pr_Write(at,0,20,(char *)&cheader.maxID,sizeof(cheader.maxID));
501 if (code != 0) return code;
502 }
503 return PRSUCCESS;
504}
505
506Initdb()
507{
508 long code;
509 struct ubik_trans *tt;
510 long len;
511 long temp;
512 long flag = 0;
513 static long initd=0;
514 static struct ubik_version curver;
515 struct ubik_version newver;
0c4439d6 516 struct ubik_hdr header;
e1f001e5 517
518 /* init the database. We'll try reading it, but if we're starting from scratch, we'll have to do a write transaction. */
519
520 code = ubik_BeginTrans(dbase,UBIK_READTRANS, &tt);
521 if (code) return code;
522 code = ubik_SetLock(tt,1,1,LOCKREAD);
523 if (code) {
524 ubik_AbortTrans(tt);
525 return code;
526 }
527 if (!initd) {
528 initd = 1;
529 bzero(&curver,sizeof(curver));
530 }
e1f001e5 531 len = sizeof(cheader);
532 code = pr_Read(tt, 0, 0, (char *) &cheader, len);
533 if (code != 0) {
534 printf("prserver: couldn't read header -code is %d\n",code);
535 ubik_AbortTrans(tt);
536 return code;
537 }
538 if (ntohl(cheader.headerSize) == sizeof(cheader) && ntohl(cheader.eofPtr) != NULL && FindByID(tt,ANONYMOUSID) != 0){
539 /* database exists, so we don't have to build it */
540 code = ubik_EndTrans(tt);
541 if (code) return code;
542 return PRSUCCESS;
543 }
544 /* else we need to build a database */
545 code = ubik_EndTrans(tt);
546 if (code) return code;
0c4439d6 547 printf("Creating new database\n");
e1f001e5 548 code = ubik_BeginTrans(dbase,UBIK_WRITETRANS, &tt);
549 if (code) return code;
550 code = ubik_SetLock(tt,1,1,LOCKWRITE);
551 if (code) {
552 ubik_AbortTrans(tt);
553 return code;
554 }
0c4439d6 555 header.magic = htonl(UBIK_MAGIC);
556 header.pad1 = 0;
557 header.size = 0;
558 header.version.epoch = header.version.counter = htonl(1);
559 code = pr_Write(tt, 0, -(HDRSIZE), (char *)&header, sizeof(header));
560 if (code != 0) {
561 printf("prserver: couldn't write ubik header - code is %d.\n", code);
562 return code;
563 }
e1f001e5 564 cheader.headerSize = htonl(sizeof(cheader));
565 code = pr_Write(tt,0,4,(char *)&cheader.headerSize,sizeof(cheader.headerSize));
566 if (code != 0) {
567 printf("prserver: couldn't write header size - code is %d.\n",code);
568 ubik_AbortTrans(tt);
569 return code;
570 }
571 cheader.eofPtr = cheader.headerSize; /* already in network order! */
572 code = pr_Write(tt,0,12,(char *)&cheader.eofPtr,sizeof(cheader.eofPtr));
573 if (code != 0) {
574 printf("prserver: couldn't write eof Ptr - code is %d.\n",code);
575 ubik_AbortTrans(tt);
576 return code;
577 }
578 temp = SYSADMINID;
579 if (FindByID(tt,SYSADMINID) == 0) {
580 /* init sysadmin */
581 flag |= PRGRP;
582 code = CreateEntry(tt,"system:administrators",&temp,1,flag,SYSADMINID,SYSADMINID);
583 if (code != PRSUCCESS) {
584 printf("prserver: couldn't create system:administrators.\n");
585 ubik_AbortTrans(tt);
586 return code;
587 }
588 flag = 0;
589 }
590 temp = ANYUSERID;
591 if ( FindByID(tt,temp) == 0) { /* init sysadmin */
592 flag |= PRGRP;
593 code = CreateEntry(tt,"system:anyuser",&temp,1,flag,SYSADMINID,SYSADMINID);
594 if (code != PRSUCCESS) {
595 printf("prserver: couldn't create system:anyuser.\n");
596 ubik_AbortTrans(tt);
597 return code;
598 }
599 flag = 0;
600 }
601 temp = AUTHUSERID;
602 if (FindByID(tt,temp) == 0) { /* init sysadmin */
603 flag |= PRGRP;
604 code = CreateEntry(tt,"system:authuser",&temp,1,flag,SYSADMINID,SYSADMINID);
605 if (code != PRSUCCESS) {
606 printf("prserver: couldn't create system:authuser.\n");
607 ubik_AbortTrans(tt);
608 return code;
609 }
610 flag = 0;
611 }
612 temp = ANONYMOUSID;
613 if (FindByID(tt,temp) == 0) { /* init sysadmin */
614 code = CreateEntry(tt,"anonymous",&temp,1,flag,SYSADMINID,SYSADMINID);
615 if (code != PRSUCCESS) {
616 printf("prserver: couldn't create anonymous.\n");
617 ubik_AbortTrans(tt);
618 return code;
619 }
620 /* well, we don't really want the max id set to anonymousid, so we'll set it back to 0 */
621 cheader.maxID = 0; /* Zero is in correct byte order no matter what! */
622 code = pr_Write(tt,0,20,(char *)&cheader.maxID,sizeof(cheader.maxID));
623 if (code) {
624 printf("prserver: couldn't set max id - code is %d.\n");
625 ubik_AbortTrans(tt);
626 return code;
627 }
628 }
629 code = ubik_EndTrans(tt);
630 if (code) return code;
631 return PRSUCCESS;
632}
633
634long NameToID(at, aname, aid)
635register struct ubik_trans *at;
636char aname[PR_MAXNAMELEN];
637long *aid;
638{
639 register long code;
640 long temp;
641 struct prentry tentry;
642
643 temp = FindByName(at,aname);
644 if (!temp) return PRNOENT;
645 code = pr_ReadEntry(at, 0, temp, &tentry);
646 if (code != 0) return code;
647 *aid = tentry.id;
648 return PRSUCCESS;
649}
650
651long IDToName(at, aid, aname)
652register struct ubik_trans *at;
653long aid;
654char aname[PR_MAXNAMELEN];
655{
656 long temp;
657 struct prentry tentry;
658 register long code;
659
660 temp = FindByID(at,aid);
661 if (!temp) return PRNOENT;
662 code = pr_ReadEntry(at,0,temp,&tentry);
663 if (code != 0) return code;
664 strncpy(aname,tentry.name,PR_MAXNAMELEN);
665 return PRSUCCESS;
666}
667
668long ChangeEntry(at, aid,cid,name,oid,newid)
669struct ubik_trans *at;
670long aid;
671long cid;
672char *name;
673long oid;
674long newid;
675{
676 register long code;
677 long pos;
678 struct prentry tentry;
679 long loc;
680 long noAuth;
681 char *check;
682 long tid;
683 char holder[PR_MAXNAMELEN];
684 char temp[PR_MAXNAMELEN];
685
686 noAuth = afsconf_GetNoAuthFlag(prdir);
687 bzero(holder,PR_MAXNAMELEN);
688 bzero(temp,PR_MAXNAMELEN);
689 loc = FindByID(at,aid);
690 if (!loc) return PRNOENT;
691 code = pr_ReadEntry(at,0,loc,&tentry);
692 if (code) return PRDBFAIL;
693 if (tentry.owner != cid && !IsAMemberOf(at,cid,SYSADMINID) && !IsAMemberOf(at,cid,tentry.owner) && !noAuth)
694 return PRPERM;
695 if (aid != newid && newid != 0) { /* then we're actually trying to change the id */
696 pos = FindByID(at,newid);
697 if (pos) return PRIDEXIST; /* new id already in use! */
698 if ((aid < 0 && newid) > 0 || (aid > 0 && newid < 0)) return PRPERM;
699 /* if new id is not in use, rehash things */
700 code = RemoveFromIDHash(at,aid,&loc);
701 if (code != PRSUCCESS) return code;
702 tentry.id = newid;
703 code = pr_WriteEntry(at,0,loc,&tentry);
704 code = AddToIDHash(at,tentry.id,loc);
705 if (code) return code;
706 }
707 if (tentry.owner != oid && oid) {
708 if (tentry.flags & PRGRP) {
709 /* switch owner chains before we lose old owner */
710 if (FindByID(at,tentry.owner)) /* if it has an owner */
711 code = RemoveFromOwnerChain(at,tentry.id,tentry.owner);
712 else /* must be an orphan */
713 code = RemoveFromOrphan(at,tentry.id);
714 if (code) return code;
715 code = AddToOwnerChain(at,tentry.id,oid);
716 if (code) return code;
717 }
718 tentry.owner = oid;
719 if ((tentry.flags & PRGRP) && (strlen(name) == 0)) {
720 /* if we change the owner of a group, it's name will change as well */
721 if (tentry.owner < 0) {
722 code = IDToName(at,tentry.owner,temp);
723 if (code) return code;
724 check = index(temp,':');
725 strncpy(holder,temp,check - temp);
726 }
727 else {
728 code = IDToName(at,tentry.owner,holder);
729 if (code) return code;
730 }
731 strncat(holder,":",PR_MAXNAMELEN);
732 /* now the rest of the name */
733 check = index(tentry.name,':');
734 strncat(holder,++check,PR_MAXNAMELEN);
735 if (strcmp(holder,tentry.name)) {
736 /* then the name really did change */
737 pos = FindByName(at,holder);
738 if (pos) return PREXIST;
739 code = RemoveFromNameHash(at,tentry.name,&loc);
740 if (code != PRSUCCESS) return code;
741 strncpy(tentry.name,holder,PR_MAXNAMELEN);
742 code = AddToNameHash(at,tentry.name,loc);
743 if (code != PRSUCCESS) return code;
744 }
745 }
746 code = pr_WriteEntry(at,0,loc,&tentry);
747 if (code) return PRDBFAIL;
748 }
749 if ((strcmp(tentry.name,name)) && (strlen(name)!= 0)) {
750 if (tentry.flags & PRGRP) {
751 if ((check = index(name,':')) == NULL) return PRBADNAM;
752 strncpy(temp,name,check-name);
753 code = NameToID(at,temp,&tid);
754 if (tid != tentry.owner) return PRPERM;
755 }
756 else
757 /* if it's not a group, shouldn't have a : in it */
758 if ((check = index(name,':')) != NULL)
759 return PRBADNAM;
760 pos = FindByName(at,name);
761 if (pos) return PREXIST;
762 code = RemoveFromNameHash(at,tentry.name,&loc);
763 if (code != PRSUCCESS) return code;
764 strncpy(tentry.name,name,PR_MAXNAMELEN);
765 code = pr_WriteEntry(at,0,loc,&tentry);
766 if (code) return PRDBFAIL;
767 code = AddToNameHash(at,tentry.name,loc);
768 if (code != PRSUCCESS) return code;
769 }
770 return PRSUCCESS;
771}
This page took 2.303603 seconds and 5 git commands to generate.