+
+#ifdef CROSS_CELL
+#define ADD_TO_AUTHUSER_GROUP 1
+#define AUTHUSER_GROUP "system:authuser"
+ {
+ char * atsign;
+
+ if (!(atsign= index(aname,'@'))) { /* No @ so local cell*/
+ if (idflag)
+ tentry.id = *aid;
+ else {
+ code= AllocID(at,flag,&tentry.id);
+ if (code != PRSUCCESS) return code;
+ }
+ } else {
+ /*foreign cells are represented by the group system:authuser@cell*/
+ if (flag & PRGRP) {
+ /* it's a new foreign cell so the format
+ * must be AUTHUSER_GROUP@cellname */
+ int badFormat;
+
+ *atsign = '\0';
+ badFormat = strcmp(AUTHUSER_GROUP, aname);
+ *atsign = '@';
+ if (badFormat) return PRBADNAM;
+ if (idflag)
+ tentry.id = *aid;
+ else {
+ code= AllocID(at,flag,&tentry.id);
+ if (code != PRSUCCESS) return code;
+ }
+ } else {
+ /* it's a foreign cell entry */
+ char *cellGroup;
+ long pos;
+ struct prentry centry;
+ extern long allocNextId();
+ extern long AddToEntry();
+
+ cellGroup = (char *) malloc (strlen(AUTHUSER_GROUP) +
+ strlen(atsign) +1);
+ strcpy(cellGroup, AUTHUSER_GROUP);
+ strcat(cellGroup, atsign);
+ pos = FindByName(at,cellGroup);
+
+ /* if the group doesn't exist don't allow user creation */
+ if (!pos) return PRBADNAM;
+
+ code = pr_Read (at, 0, pos, ¢ry, sizeof(centry));
+ if (code) return code;
+ tentry.cellid = ntohl(centry.id);
+ /* cellid is the id of the group representing the cell */
+
+ if (idflag) {
+ if (!inRange(¢ry,*aid))
+ return PRBADARG; /* the id specified is not in
+ * the id space of the group */
+ tentry.id = *aid;
+ } else
+ /* allocNextID() will allocate the next id
+ * in that cell's space */
+ tentry.id = allocNextId(¢ry);
+
+ /* charge the cell group for the new user and test quota */
+ if (!(ntohl(centry.flags) & PRQUOTA)) {
+ /* quota uninitialized, so initialize it now */
+ centry.flags = htonl (ntohl(centry.flags) | PRQUOTA);
+ centry.ngroups = htonl(30);
+ }
+
+ centry.ngroups = htonl(ntohl(centry.ngroups) - 1);
+ if ( centry.ngroups < 0)
+ if (!pr_noAuth) return PRNOMORE;
+
+#if !ADD_TO_AUTHUSER_GROUP
+ centry.count = htonl(ntohl(centry.ngroups) +1);
+ /* keep count of how many people are in the group. */
+#endif
+
+ code = pr_Write (at, 0, pos, ¢ry, sizeof(centry));
+ /* write updated entry for group */
+
+ /* Now add the new user entry to the database */
+
+ tentry.creator = creator;
+ *aid = tentry.id;
+ code = pr_WriteEntry(at, 0, newEntry, &tentry);
+ if (code) return PRDBFAIL;
+ code = AddToIDHash(at,*aid,newEntry);
+ if (code != PRSUCCESS) return code;
+ code = AddToNameHash(at,aname,newEntry);
+ if (code != PRSUCCESS) return code;
+ if (inc_header_word (at, foreigncount, 1)) return PRDBFAIL;
+
+#if ADD_TO_AUTHUSER_GROUP
+
+ /* Now add the entry to the authuser group for this cell.
+ * We will reread the entries for the user and the group
+ * instead of modifying them before writing them in the
+ * previous steps. Although not very efficient, much simpler */
+
+ /* First update the group entry */
+ pos = FindByID(at,tentry.cellid);
+ if (!pos) return PRBADNAM;
+ code = pr_ReadEntry (at, 0, pos, ¢ry);
+ if (code) return code;
+ code = AddToEntry(at, ¢ry,pos,*aid);
+ if (code) return code;
+ /* and now the user entry */
+ pos = FindByID(at,*aid);
+ if (!pos) return PRBADNAM;
+ code = pr_ReadEntry(at, 0, pos, &tentry);
+ if (code) return code;
+ code = AddToEntry(at, &tentry,pos,tentry.cellid);
+ if (code) return code;
+
+#endif
+
+ /* Ok we're done */
+ return PRSUCCESS;
+ }
+ }
+ }
+
+#else /* !CROSS_CELL */
+