populate cs_inet_email with a default generated address ... we need it for XMPP
[citadel.git] / citadel / user_ops.c
index 7e82d3188184a900b491414c1fb59dca31dd1712..32734200e55b19f633760e961e2c6943d8b24ee1 100644 (file)
@@ -56,7 +56,7 @@ int CtdlGetUser(struct ctdluser *usbuf, char *name)
                memcpy(usbuf, cdbus->ptr, ((cdbus->len > sizeof(struct ctdluser)) ?  sizeof(struct ctdluser) : cdbus->len));
        }
        cdb_free(cdbus);
-       return (0);
+       return(0);
 }
 
 
@@ -78,7 +78,7 @@ int CtdlGetUserLock(struct ctdluser *usbuf, char *name)
        if (retcode == 0) {
                begin_critical_section(S_USERS);
        }
-       return (retcode);
+       return(retcode);
 }
 
 
@@ -188,7 +188,7 @@ int GenerateRelationshipIndex(char *IndexBuf,
        TheIndex.iUserID = UserID;
 
        memcpy(IndexBuf, &TheIndex, sizeof(TheIndex));
-       return (sizeof(TheIndex));
+       return(sizeof(TheIndex));
 }
 
 
@@ -241,19 +241,14 @@ void CtdlGetRelationship(visit *vbuf,
        struct cdbdata *cdbvisit;
 
        /* Generate an index */
-       IndexLen = GenerateRelationshipIndex(IndexBuf,
-                                            rel_room->QRnumber,
-                                            rel_room->QRgen,
-                                            rel_user->usernum);
+       IndexLen = GenerateRelationshipIndex(IndexBuf, rel_room->QRnumber, rel_room->QRgen, rel_user->usernum);
 
        /* Clear out the buffer */
        memset(vbuf, 0, sizeof(visit));
 
        cdbvisit = cdb_fetch(CDB_VISIT, IndexBuf, IndexLen);
        if (cdbvisit != NULL) {
-               memcpy(vbuf, cdbvisit->ptr,
-                      ((cdbvisit->len > sizeof(visit)) ?
-                       sizeof(visit) : cdbvisit->len));
+               memcpy(vbuf, cdbvisit->ptr, ((cdbvisit->len > sizeof(visit)) ?  sizeof(visit) : cdbvisit->len));
                cdb_free(cdbvisit);
        }
        else {
@@ -351,9 +346,9 @@ int CtdlAccessCheck(int required_level)
 int is_aide(void)
 {
        if (CC->user.axlevel >= AxAideU)
-               return (1);
+               return(1);
        else
-               return (0);
+               return(0);
 }
 
 
@@ -364,13 +359,13 @@ int is_room_aide(void)
 {
 
        if (!CC->logged_in) {
-               return (0);
+               return(0);
        }
 
        if ((CC->user.axlevel >= AxAideU) || (CC->room.QRroomaide == CC->user.usernum)) {
-               return (1);
+               return(1);
        } else {
-               return (0);
+               return(0);
        }
 }
 
@@ -449,32 +444,32 @@ void rebuild_usersbynumber(void) {
 
 
 /*
- * getuserbyuid()  -     get user by system uid (for PAM mode authentication)
- *                    returns 0 if user was found
- *
- * WARNING:    don't use this function unless you absolutely have to.  It does
- *             a sequential search and therefore is computationally expensive.
- *
- * FIXME:      build an index, dummy.
+ * getuserbyuid()      Get user by system uid (for PAM mode authentication)
+ *                     Returns 0 if user was found
+ *                     This now uses an extauth index.
  */
 int getuserbyuid(struct ctdluser *usbuf, uid_t number)
 {
-       struct cdbdata *cdbus;
+       struct cdbdata *cdbextauth;
+       long usernum = 0;
+       StrBuf *claimed_id;
+
+       claimed_id = NewStrBuf();
+       StrBufPrintf(claimed_id, "uid:%d", number);
+       cdbextauth = cdb_fetch(CDB_EXTAUTH, ChrPtr(claimed_id), StrLength(claimed_id));
+       FreeStrBuf(&claimed_id);
+       if (cdbextauth == NULL) {
+               return(-1);
+       }
 
-       cdb_rewind(CDB_USERS);
+       memcpy(&usernum, cdbextauth->ptr, sizeof(long));
+       cdb_free(cdbextauth);
 
-       while (cdbus = cdb_next_item(CDB_USERS), cdbus != NULL) {
-               memset(usbuf, 0, sizeof(struct ctdluser));
-               memcpy(usbuf, cdbus->ptr,
-                      ((cdbus->len > sizeof(struct ctdluser)) ?
-                       sizeof(struct ctdluser) : cdbus->len));
-               cdb_free(cdbus);
-               if (usbuf->uid == number) {
-                       cdb_close_cursor(CDB_USERS);
-                       return (0);
-               }
+       if (!CtdlGetUserByNumber(usbuf, usernum)) {
+               return(0);
        }
-       return (-1);
+
+       return(-1);
 }
 
 
@@ -594,9 +589,7 @@ int CtdlLoginExistingUser(char *authname, const char *trythisname)
                /* First, try to log in as if the supplied name is a display name */
                found_user = CtdlGetUser(&CC->user, username);
        
-               /* If that didn't work, try to log in as if the supplied name
-               * is an e-mail address
-               */
+               /* If that didn't work, try to log in as if the supplied name * is an e-mail address */
                if (found_user != 0) {
                        valid = validate_recipients(username, NULL, 0);
                        if (valid != NULL) {
@@ -626,65 +619,63 @@ int CtdlLoginExistingUser(char *authname, const char *trythisname)
  */
 void do_login(void)
 {
-       struct CitContext *CCC = CC;
+       CC->logged_in = 1;
+       syslog(LOG_NOTICE, "user_ops: <%s> logged in", CC->curr_user);
 
-       CCC->logged_in = 1;
-       syslog(LOG_NOTICE, "user_ops: <%s> logged in", CCC->curr_user);
-
-       CtdlGetUserLock(&CCC->user, CCC->curr_user);
-       ++(CCC->user.timescalled);
-       CCC->previous_login = CCC->user.lastcall;
-       time(&CCC->user.lastcall);
+       CtdlGetUserLock(&CC->user, CC->curr_user);
+       ++(CC->user.timescalled);
+       CC->previous_login = CC->user.lastcall;
+       time(&CC->user.lastcall);
 
        /* If this user's name is the name of the system administrator
         * (as specified in setup), automatically assign access level 6.
         */
-       if (!strcasecmp(CCC->user.fullname, CtdlGetConfigStr("c_sysadm"))) {
-               CCC->user.axlevel = AxAideU;
+       if ( (!IsEmptyStr(CtdlGetConfigStr("c_sysadm"))) && (!strcasecmp(CC->user.fullname, CtdlGetConfigStr("c_sysadm"))) ) {
+               CC->user.axlevel = AxAideU;
        }
 
        /* If we're authenticating off the host system, automatically give
         * root the highest level of access.
         */
        if (CtdlGetConfigInt("c_auth_mode") == AUTHMODE_HOST) {
-               if (CCC->user.uid == 0) {
-                       CCC->user.axlevel = AxAideU;
+               if (CC->user.uid == 0) {
+                       CC->user.axlevel = AxAideU;
                }
        }
+       CtdlPutUserLock(&CC->user);
 
        /*
         * If we are using LDAP authentication, extract the user's email addresses from the directory.
-        * FIXME make this a site configurable setting
         */
-       #ifdef HAVE_LDAP
-               if ((CtdlGetConfigInt("c_auth_mode") == AUTHMODE_LDAP) || (CtdlGetConfigInt("c_auth_mode") == AUTHMODE_LDAP_AD)) {
-                       char new_emailaddrs[512];
-                       if (extract_email_addresses_from_ldap(CCC->ldap_dn, new_emailaddrs) == 0) {
-                               strcpy(CCC->user.emailaddrs, new_emailaddrs);
+#ifdef HAVE_LDAP
+       if ((CtdlGetConfigInt("c_auth_mode") == AUTHMODE_LDAP) || (CtdlGetConfigInt("c_auth_mode") == AUTHMODE_LDAP_AD)) {
+               char new_emailaddrs[512];
+               if (CtdlGetConfigInt("c_ldap_sync_email_addrs") > 0) {
+                       if (extract_email_addresses_from_ldap(CC->ldap_dn, new_emailaddrs) == 0) {
+                               CtdlSetEmailAddressesForUser(CC->user.fullname, new_emailaddrs);
                        }
                }
-       #endif
+       }
+#endif
 
        /*
-        * No email address for user?  Make one up.
+        * No email address for user?  Make one up.  (Apparently this broke something in the past.  What was it?)
         */
-       if (IsEmptyStr(CCC->user.emailaddrs)) {
-               sprintf(CCC->user.emailaddrs, "cit%ld@%s", CCC->user.usernum, CtdlGetConfigStr("c_fqdn"));
+       if (IsEmptyStr(CC->user.emailaddrs)) {
+               sprintf(CC->user.emailaddrs, "cit%ld@%s", CC->user.usernum, CtdlGetConfigStr("c_fqdn"));
        }
-       
-       CtdlPutUserLock(&CCC->user);
 
        /*
         * Populate cs_inet_email and cs_inet_other_emails with valid email addresses from the user record
         */
-       strcpy(CCC->cs_inet_email, CCC->user.emailaddrs);
-       char *firstsep = strstr(CCC->cs_inet_email, "|");
+       strcpy(CC->cs_inet_email, CC->user.emailaddrs);
+       char *firstsep = strstr(CC->cs_inet_email, "|");
        if (firstsep) {
-               strcpy(CCC->cs_inet_other_emails, firstsep+1);
+               strcpy(CC->cs_inet_other_emails, firstsep+1);
                *firstsep = 0;
        }
        else {
-               CCC->cs_inet_other_emails[0] = 0;
+               CC->cs_inet_other_emails[0] = 0;
        }
 
        /* Create any personal rooms required by the system.
@@ -956,12 +947,13 @@ int purge_user(char pname[])
 
        /* If the name is empty we can't find them in the DB any way so just return */
        if (IsEmptyStr(pname))
-               return (ERROR + NO_SUCH_USER);
+               return(ERROR + NO_SUCH_USER);
 
        if (CtdlGetUser(&usbuf, pname) != 0) {
                syslog(LOG_ERR, "user_ops: cannot purge user <%s> - not found", pname);
-               return (ERROR + NO_SUCH_USER);
+               return(ERROR + NO_SUCH_USER);
        }
+
        /* Don't delete a user who is currently logged in.  Instead, just
         * set the access level to 0, and let the account get swept up
         * during the next purge.
@@ -970,19 +962,10 @@ int purge_user(char pname[])
                syslog(LOG_WARNING, "user_ops: <%s> is logged in; not deleting", pname);
                usbuf.axlevel = AxDeleted;
                CtdlPutUser(&usbuf);
-               return (1);
+               return(1);
        }
-       syslog(LOG_NOTICE, "user_ops: deleting <%s>", pname);
 
-/*
- * FIXME:
- * This should all be wrapped in a S_USERS mutex.
- * Without the mutex the user could log in before we get to the next function
- * That would truly mess things up :-(
- * I would like to see the S_USERS start before the CtdlIsUserLoggedInByNum() above
- * and end after the user has been deleted from the database, below.
- * Question is should we enter the EVT_PURGEUSER while S_USERS is active?
- */
+       syslog(LOG_NOTICE, "user_ops: deleting <%s>", pname);
 
        /* Perform any purge functions registered by server extensions */
        PerformUserHooks(&usbuf, EVT_PURGEUSER);
@@ -996,14 +979,14 @@ int purge_user(char pname[])
        /* delete the userlog entry */
        cdb_delete(CDB_USERS, usernamekey, strlen(usernamekey));
 
-       return (0);
+       return(0);
 }
 
 
 int internal_create_user(char *username, struct ctdluser *usbuf, uid_t uid)
 {
        if (!CtdlGetUser(usbuf, username)) {
-               return (ERROR + ALREADY_EXISTS);
+               return(ERROR + ALREADY_EXISTS);
        }
 
        /* Go ahead and initialize a new user record */
@@ -1028,14 +1011,14 @@ int internal_create_user(char *username, struct ctdluser *usbuf, uid_t uid)
        cdb_store(CDB_USERSBYNUMBER, &usbuf->usernum, sizeof(long), usbuf->fullname, strlen(usbuf->fullname)+1);
 
        /* If non-native auth, index by uid */
-       if (usbuf->uid > 0) {
+       if ((usbuf->uid > 0) && (usbuf->uid != NATIVE_AUTH_UID)) {
                StrBuf *claimed_id = NewStrBuf();
                StrBufPrintf(claimed_id, "uid:%d", usbuf->uid);
                attach_extauth(usbuf, claimed_id);
                FreeStrBuf(&claimed_id);
        }
 
-       return 0;
+       return(0);
 }
 
 
@@ -1089,7 +1072,7 @@ int create_user(char *username, int become_user, uid_t uid)
        
                /* Check to make sure we're still who we think we are */
                if (CtdlGetUser(&CC->user, CC->curr_user)) {
-                       return (ERROR + INTERNAL_ERROR);
+                       return(ERROR + INTERNAL_ERROR);
                }
        }
        
@@ -1101,7 +1084,7 @@ int create_user(char *username, int become_user, uid_t uid)
        );
        CtdlAideMessage(buf, "User Creation Notice");
        syslog(LOG_NOTICE, "user_ops: <%s> created", username);
-       return (0);
+       return(0);
 }
 
 
@@ -1152,7 +1135,6 @@ int CtdlInvtKick(char *iuser, int op) {
                (CC->logged_in ? CC->user.fullname : "an administrator")
        );
        CtdlAideMessage(bbb,"User Admin Message");
-
        return(0);
 }
 
@@ -1182,7 +1164,6 @@ int CtdlForgetThisRoom(void) {
        /* Return to the Lobby, so we don't end up in an undefined room */
        CtdlUserGoto(CtdlGetConfigStr("c_baseroom"), 0, 0, NULL, NULL, NULL, NULL);
        return(0);
-
 }
 
 
@@ -1242,11 +1223,9 @@ void ListThisUser(struct ctdluser *usbuf, void *data)
 int NewMailCount()
 {
        int num_newmsgs = 0;
-
        num_newmsgs = CC->newmail;
        CC->newmail = 0;
-
-       return (num_newmsgs);
+       return(num_newmsgs);
 }
 
 
@@ -1266,7 +1245,7 @@ int InitialMailCheck()
 
        CtdlMailboxName(mailboxname, sizeof mailboxname, &CC->user, MAILROOM);
        if (CtdlGetRoom(&mailbox, mailboxname) != 0)
-               return (0);
+               return(0);
        CtdlGetRelationship(&vbuf, &CC->user, &mailbox);
 
        cdbfr = cdb_fetch(CDB_MSGLISTS, &mailbox.QRnumber, sizeof(long));
@@ -1288,5 +1267,5 @@ int InitialMailCheck()
        if (msglist != NULL)
                free(msglist);
 
-       return (num_newmsgs);
+       return(num_newmsgs);
 }