home *** CD-ROM | disk | FTP | other *** search
/ PC World 2003 February / PCWorld_2003-02_cd.bin / Komunik / sambar / sambar53b3.exe / samples / source / LOGIN.C < prev    next >
Encoding:
C/C++ Source or Header  |  2002-09-27  |  57.3 KB  |  2,319 lines

  1. /*
  2. ** LOGIN
  3. **
  4. **      HTTP Wrapper for the Login/Logout/Profile Management Library
  5. **
  6. **        Confidential Property of Tod Sambar
  7. **        (c) Copyright Tod Sambar 1996-1997
  8. **        All rights reserved.
  9. **
  10. **
  11. ** Public Functions:
  12. **
  13. **        login_init
  14. **        user_login
  15. **        user_logout
  16. **        user_profile
  17. **        user_add
  18. **        user_delete
  19. **        user_update
  20. **        user_passwd
  21. **        user_list
  22. **        user_select
  23. **        user_maillist
  24. **        user_mailbox
  25. **        group_add
  26. **        group_delete
  27. **        group_list
  28. **        group_select
  29. **        ftp_connect
  30. **        mail_connect
  31. **        telnet_connect
  32. **
  33. **
  34. ** History:
  35. ** Chg#    Date    Description                                                Resp
  36. ** ----    -------    -------------------------------------------------------    ----
  37. **         27JAN96    Created                                                    sambar
  38. **         29MAR97    Added user list and update functions                    sambar
  39. **         30MAR97    Added FTP connection security                            sambar
  40. **         10OCT97    Added user password interface                            sambar
  41. **        14NOV97 Added group management                                    sambar
  42. **         28OCT98    Added MAIL connection security                            sambar
  43. */
  44.  
  45. #include    <stdio.h>
  46. #include    <stdlib.h>
  47. #include    <memory.h>
  48. #include    <string.h>
  49. #include    <login.h>
  50.  
  51. #ifndef    WIN32
  52. #include    <string.h>
  53. #else
  54. #include    <direct.h>
  55. #endif    /* WIN32 */
  56.  
  57. /*
  58. ** Login RPC Commands
  59. */
  60. typedef struct login__rpcs
  61. {
  62.     SA_CHAR        *name;
  63.     SA_RPCPARAM    *params;
  64.     SA_INT        numparams;
  65.     SA_INT        auth;
  66.     SA_VOID        *func;
  67.     SA_CHAR        *descr;
  68. } LOGIN__RPCS;
  69.  
  70. static SA_RPCPARAM    adduserp [] =
  71. {
  72.     { "username",     1,    "User login." },
  73.     { "password",     0,    "User password." },
  74.     { "group",         0,    "User group." },
  75.     { "name",         0,    "User name." },
  76.     { "dir",         0,    "Ftp/Document Manager directory of the user." },
  77.     { "makedir",    0,    "Create the user directory." },
  78.     { "ftpprivs",     1,    "Upload priviledges of the user." },
  79.     { "ftpmax",     1,    "FTP/Document Manager maximum upload (MB)." },
  80.     { "mbox",         0,    "Create a mailbox for the user." }
  81. };
  82. static SA_RPCPARAM    upduserp [] =
  83. {
  84.     { "username",     1,    "User login." },
  85.     { "password",     0,    "User password." },
  86.     { "group",         0,    "User group." },
  87.     { "name",         0,    "User name." },
  88.     { "dir",         0,    "Ftp/Document Manager directory of the user." },
  89.     { "makedir",    0,    "Create the user directory." },
  90.     { "ftpprivs",     1,    "Upload priviledges of the user." },
  91.     { "ftpmax",     1,    "FTP/Document Manager maximum upload (MB)." },
  92.     { "mbox",         0,    "Create a mailbox for the user." }
  93. };
  94. static SA_RPCPARAM    deluserp [] =
  95. {
  96.     { "username",     1,    "User login." }
  97. };
  98. static SA_RPCPARAM    userpropp [] =
  99. {
  100.     { "username",     1,    "User login." },
  101.     { "prop",     1,    "User property: group,password,name,dir,ftpprivs,ftpmax" }
  102. };
  103. static SA_RPCPARAM    selectuserp [] =
  104. {
  105.     { "username",     0,    "User login." },
  106. };
  107. static SA_RPCPARAM    addgroupp [] =
  108. {
  109.     { "groupname",     1,    "Symbolic name of the group." }
  110. };
  111. static SA_RPCPARAM    delgroupp [] =
  112. {
  113.     { "groupname",     1,    "Symbolic name of the group." }
  114. };
  115. static SA_RPCPARAM    selectgroupp [] =
  116. {
  117.     { "username",     0,    "User to test against group list." }
  118. };
  119. static SA_RPCPARAM    userpasswdp [] =
  120. {
  121.     { "username",     1,    "User login." },
  122.     { "password",     0,    "Existing password for the user." },
  123.     { "newpasswd",     0,    "New password for the user." },
  124.     { "confpasswd",    0,    "Confirm new password." }
  125. };
  126. static SA_RPCPARAM    usermboxp [] =
  127. {
  128.     { "username",     1,    "User login." },
  129.     { "action",     1,    "Create/Delete user mailbox." }
  130. };
  131.  
  132. static LOGIN__RPCS        login_rpcs [] =
  133. {
  134.     { "adduser",     adduserp,    sizeof(adduserp)/sizeof(SA_RPCPARAM),
  135.        SA_AUTHORIZATION_ADMIN,    (SA_VOID *)user_add,
  136.       "Add a user to the system." },
  137.     { "upduser",     upduserp,    sizeof(upduserp)/sizeof(SA_RPCPARAM),    
  138.       SA_AUTHORIZATION_ADMIN,     (SA_VOID *)user_update,
  139.       "Update a user." }, 
  140.     { "deluser",    deluserp,    sizeof(deluserp)/sizeof(SA_RPCPARAM),     
  141.        SA_AUTHORIZATION_ADMIN,     (SA_VOID *)user_delete,
  142.       "Delete a user from the system." },
  143.     { "userprop",    userpropp,    sizeof(userpropp)/sizeof(SA_RPCPARAM),     
  144.       SA_AUTHORIZATION_ADMIN,     (SA_VOID *)user_prop,
  145.       "Get a single user attribute for display." },
  146.     { "listusers",    NULL, 0,
  147.       SA_AUTHORIZATION_ADMIN,     (SA_VOID *)user_list,
  148.       "List users for update/delete." },
  149.     { "selectuser",    selectuserp,sizeof(selectuserp)/sizeof(SA_RPCPARAM),    
  150.       SA_AUTHORIZATION_ADMIN,     (SA_VOID *)user_select,
  151.       "List users for selection in a pick list." },
  152.     { "mailusers",    NULL, 0,
  153.       SA_AUTHORIZATION_ADMIN,     (SA_VOID *)user_maillist,
  154.       "List mail users for update/delete." },
  155.     { "usermbox",    usermboxp,    sizeof(usermboxp)/sizeof(SA_RPCPARAM),    
  156.       SA_AUTHORIZATION_ADMIN,     (SA_VOID *)user_mailbox,
  157.       "Create/Delete a user mailbox." },
  158.  
  159.     { "addgroup",    addgroupp,    sizeof(addgroupp)/sizeof(SA_RPCPARAM),     
  160.       SA_AUTHORIZATION_ADMIN,    (SA_VOID *)group_add,
  161.       "Add a group to the system." },
  162.     { "delgroup",     delgroupp,    sizeof(delgroupp)/sizeof(SA_RPCPARAM),    
  163.       SA_AUTHORIZATION_ADMIN,     (SA_VOID *)group_delete,
  164.       "Delete a group from the system." },
  165.     { "listgroups",    NULL, 0,
  166.       SA_AUTHORIZATION_ADMIN,     (SA_VOID *)group_list,
  167.       "List groups for delete." },
  168.     { "selectgroup",selectgroupp,    sizeof(selectgroupp)/sizeof(SA_RPCPARAM),
  169.       SA_AUTHORIZATION_ADMIN,     (SA_VOID *)group_select,
  170.       "List groups for selection in a pick list." },
  171.  
  172.     { "userpasswd",    userpasswdp,    sizeof(userpasswdp)/sizeof(SA_RPCPARAM),    
  173.       SA_AUTHORIZATION_ALL,        (SA_VOID *)user_passwd,
  174.       "Interface to allow users to change their password." }
  175. };
  176.  
  177. /*
  178. ** Local Prototypes
  179. */
  180. static SA_BOOL     user__inlist(SA_CHAR *list, SA_INT listlen, 
  181.                     SA_CHAR *value, SA_INT valuelen);
  182.  
  183. /*
  184. **  LOGIN_INIT
  185. **
  186. **    Initialize the Login/Logout/Profile Interfaces for use by the 
  187. **    Sambar Server plugins.
  188. **
  189. **
  190. **  Parameters:
  191. **    sactx        Sambar Server context
  192. **
  193. **  Returns:
  194. **    SA_SUCCEED | SA_FAIL
  195. */
  196. SA_RETCODE SA_PUBLIC
  197. login_init(sactx)
  198. SA_CTX        *sactx;
  199. {
  200.     int        i;
  201.  
  202.     /* Register the User RPCs with the server                            */
  203.     for (i = 0; i < sizeof(login_rpcs) / sizeof(LOGIN__RPCS); i++)
  204.     {
  205.         if (sa_cmd_init(sactx, login_rpcs[i].name, login_rpcs[i].params, 
  206.             login_rpcs[i].numparams, login_rpcs[i].auth, login_rpcs[i].descr,
  207.             (SA_RPCFUNC)login_rpcs[i].func) != SA_SUCCEED)
  208.         {
  209.             sa_log2(sactx, SA_LOG_ERROR,
  210.                 "Unable to initialize User Management RPCs");
  211.             return (SA_FAIL);
  212.         } 
  213.     }
  214.  
  215.     sa_log2(sactx, SA_LOG_TRACE, "Login/Logout/Profile Management Initialized");
  216.  
  217.     return (SA_SUCCEED);
  218. }
  219.  
  220. /*
  221. **  USER_LOGIN
  222. **
  223. **    Login a user.  Verify the username/password against the Sambar Server
  224. **    password interfaces.  Store some profile information for use.
  225. **
  226. **  Parameters:
  227. **    sactx            Sambar Server Application context to release.
  228. **    saconn            Sambar Server User Connection handle.
  229. **    username        Name of the user logging in.
  230. **    usernamelen        Length of the user name
  231. **    password        Password of the user logging in.
  232. **    passwordlen        Length of the password.
  233. **    infop            Error return code
  234. **
  235. **  Return Values:
  236. **    SA_SUCCESS | SA_FAIL
  237. */
  238. SA_RETCODE SA_PUBLIC
  239. user_login(sactx, saconn, username, usernamelen, password, passwordlen, infop)
  240. SA_CTX        *sactx;
  241. SA_CONN        *saconn;
  242. SA_CHAR        *username;
  243. SA_INT        usernamelen;
  244. SA_CHAR        *password;
  245. SA_INT        passwordlen;
  246. SA_INT        *infop;
  247. {
  248.     SA_INT                len;
  249.     SA_INT                namelen;
  250.     SA_BOOL                ntauth;
  251.     SA_BOOL                sqlauth;
  252.     SA_BOOL                radiusauth;
  253.     SA_BOOL                status;
  254.     SA_BOOL                usepasswd;
  255.     SA_PASSWD            passwd;
  256.     LOGIN_PROFILE        *profile;
  257.     SA_CHAR                name[62];
  258.     SA_CHAR                buffer[512];
  259.  
  260.     ntauth = 0;
  261.     if (sa_ctx_props(sactx, SA_GET, SA_CTXPROP_NTAUTH, name, 30, 
  262.         (SA_INT *)NULL) == SA_SUCCEED)
  263.     {
  264.         if (stricmp(name, "true") == 0)
  265.             ntauth = 1;
  266.     }
  267.  
  268.     radiusauth = 0;
  269.     if (sa_ctx_props(sactx, SA_GET, SA_CTXPROP_RADIUSAUTH, name, 30, 
  270.         (SA_INT *)NULL) == SA_SUCCEED)
  271.     {
  272.         if (stricmp(name, "true") == 0)
  273.             radiusauth = 1;
  274.     }
  275.  
  276.     sqlauth = 0;
  277.     if (sa_ctx_props(sactx, SA_GET, SA_CTXPROP_SQLAUTH, name, 30, 
  278.         (SA_INT *)NULL) == SA_SUCCEED)
  279.     {
  280.         if (stricmp(name, "true") == 0)
  281.             sqlauth = 1;
  282.     }
  283.  
  284.     if (usernamelen == 0)
  285.     {
  286.         *infop = SA_E_INVALIDLOGIN;
  287.         return (SA_FAIL);
  288.     }
  289.  
  290.     usepasswd = 0;
  291.     if ((ntauth) || (radiusauth))
  292.     {
  293.         if ((sa_passwd_verify(sactx, username, usernamelen, password, 
  294.             passwordlen, &status) != SA_SUCCEED) ||
  295.             (!status))
  296.         {
  297.             (SA_VOID)sa_conn_props(saconn, SA_GET, SA_CONNPROP_HOST, name, 60,
  298.                 &namelen);
  299.             name[namelen] = '\0';
  300.             sprintf(buffer, 
  301.                 "%sLogin for user '%s' failed - bad password [host %s]",
  302.                 (radiusauth ? "Radius " : (ntauth ? "NT " : "")),
  303.                 username, name);
  304.             sa_log2(sactx, SA_LOG_WARN, buffer);
  305.             *infop = SA_E_INVALIDLOGIN;
  306.             return (SA_FAIL);
  307.         }
  308.  
  309.         /* Lookup the config/password entry for overrides.                */
  310.         if (sa_passwd_lookup(sactx, username, usernamelen, &passwd) 
  311.             == SA_SUCCEED)
  312.         {
  313.             usepasswd = 1;
  314.         }
  315.     }
  316.     else if (sqlauth)
  317.     {
  318.         usepasswd = 1;
  319.         if (sa_passwd_sqlauth(sactx, saconn, username, usernamelen, password, 
  320.             passwordlen, &passwd) != SA_SUCCEED)
  321.         {
  322.             (SA_VOID)sa_conn_props(saconn, SA_GET, SA_CONNPROP_HOST, name, 
  323.                 60, &namelen);
  324.             name[namelen] = '\0';
  325.             sprintf(buffer, "SQL Login for user '%s' failed [host %s]", 
  326.                 username, name);
  327.             sa_log2(sactx, SA_LOG_WARN, buffer);
  328.             *infop = SA_E_INVALIDLOGIN;
  329.             return (SA_FAIL);
  330.         }
  331.     }
  332.     else
  333.     {
  334.         usepasswd = 1;
  335.         if (sa_passwd_lookup(sactx, username, usernamelen, &passwd) 
  336.             != SA_SUCCEED)
  337.         {
  338.             (SA_VOID)sa_conn_props(saconn, SA_GET, SA_CONNPROP_HOST, name, 
  339.                 60, &namelen);
  340.             name[namelen] = '\0';
  341.             sprintf(buffer, "Login for user '%s' failed [host %s]", 
  342.                 username, name);
  343.             sa_log2(sactx, SA_LOG_WARN, buffer);
  344.             *infop = SA_E_INVALIDLOGIN;
  345.             return (SA_FAIL);
  346.         }
  347.  
  348.         /* Verify the passwords are the same                            */
  349.         if ((passwd.passwordlen != passwordlen) ||
  350.             (strncmp(passwd.password, password, passwordlen) != 0))
  351.         {
  352.             (SA_VOID)sa_conn_props(saconn, SA_GET, SA_CONNPROP_HOST, name, 60,
  353.                 &namelen);
  354.             name[namelen] = '\0';
  355.             sprintf(buffer, 
  356.                 "Login for user '%s' failed - bad password [host %s]",
  357.                 username, name);
  358.             sa_log2(sactx, SA_LOG_WARN, buffer);
  359.             *infop = SA_E_INVALIDLOGIN;
  360.             return (SA_FAIL);
  361.         }
  362.     }
  363.  
  364.     /* Allocate and populate a user profile structure                    */
  365.     profile = (LOGIN_PROFILE *)malloc(sizeof(LOGIN_PROFILE));
  366.     if (profile == (LOGIN_PROFILE *)NULL)
  367.     {
  368.         sprintf(buffer, "Login for user '%s' failed - no memory", username);
  369.         sa_log2(sactx, SA_LOG_WARN, buffer);
  370.         *infop = SA_E_INVALIDLOGIN;
  371.         return (SA_FAIL);
  372.     }
  373.  
  374.     memset(profile, 0, sizeof(LOGIN_PROFILE));
  375.     memcpy(profile->name, username, usernamelen);
  376.     profile->name[usernamelen] = '\0';
  377.     memcpy(profile->username, username, usernamelen);
  378.     profile->username[usernamelen] = '\0';
  379.     strcpy(profile->dir, "/");
  380.     strcpy(profile->group, SA_DEFAULT_GROUP);
  381.     profile->privs = SA_PRIV_NOACCESS;
  382.  
  383.     if (usepasswd)
  384.     {
  385.         profile->privs = passwd.privs;
  386.  
  387.         if (passwd.namelen > 0)
  388.         {
  389.             memcpy(profile->name, passwd.name, passwd.namelen);
  390.             profile->name[passwd.namelen] = '\0';
  391.         }
  392.  
  393.         if (passwd.grouplen > 0)
  394.         {
  395.             memcpy(profile->group, passwd.group, passwd.grouplen);
  396.             profile->group[passwd.grouplen] = '\0';
  397.         }
  398.  
  399.         if (passwd.dirlen > 0)
  400.         {
  401.             if (sa_conn_maptourl(saconn, passwd.dir, profile->dir) 
  402.                 != SA_SUCCEED)
  403.             {
  404.                 strcpy(profile->dir, passwd.dir);
  405.             }
  406.  
  407.             /* Strip the trailing slash if found.                        */
  408.             len = strlen(profile->dir);
  409.             if ((len > 1) && (profile->dir[len - 1] == '/'))
  410.                 profile->dir[len - 1] = '\0';
  411.         }
  412.     }
  413.  
  414.     /*
  415.     ** The DAVdir is the WebDAV/Document Manager root directory.
  416.     ** If the user's profile directory is "below" the Document Directory
  417.     ** we map the davdir to the Document Directory "root".
  418.     */
  419.     if (sa_conn_maptodavdir(saconn, profile->dir, profile->davdir) 
  420.         != SA_SUCCEED)
  421.     {
  422.         strcpy(profile->davdir, profile->dir);
  423.     }
  424.  
  425.     /* Load the internal server profile for the user                    */
  426.     (SA_VOID)sa_profile_init(sactx, username, usernamelen, &profile->data);
  427.  
  428.     /* Save the user's root directory for security restrictions         */
  429.     if (sa_conn_props(saconn, SA_SET, SA_CONNPROP_ROOTDIR, profile->dir,
  430.         SA_NULLTERM, (SA_INT *)NULL) != SA_SUCCEED)
  431.     {
  432.         (SA_VOID)free(profile);
  433.         sa_log2(sactx, SA_LOG_ERROR,
  434.             "sa_conn_key(SET, ROOTDIR) failed!");
  435.         return (SA_FAIL);
  436.     }
  437.  
  438.     /* Save the user's upload priviledges for security restrictions        */
  439.     if (sa_conn_props(saconn, SA_SET, SA_CONNPROP_PRIVS, 
  440.         (SA_BYTE *)&profile->privs, sizeof(SA_INT), (SA_INT *)NULL) 
  441.         != SA_SUCCEED)
  442.     {
  443.         (SA_VOID)free(profile);
  444.         sa_log2(sactx, SA_LOG_ERROR,
  445.             "sa_conn_key(SET, PRIVS) failed!");
  446.         return (SA_FAIL);
  447.     }
  448.  
  449.     /* Save the user's group                                            */
  450.     if (usepasswd)
  451.     {
  452.         if (sa_conn_props(saconn, SA_SET, SA_CONNPROP_GROUP, 
  453.             profile->group, SA_NULLTERM, (SA_INT *)NULL) != SA_SUCCEED)
  454.         {
  455.             (SA_VOID)free(profile);
  456.             sa_log2(sactx, SA_LOG_ERROR,
  457.                 "sa_conn_key(SET, GROUP) failed!");
  458.             return (SA_FAIL);
  459.         }
  460.     }
  461.  
  462.     /* Save the user's profile handle with the user connection            */
  463.     if (sa_conn_key(saconn, SA_SET, LOGIN_PROFILE_KEY, (SA_VOID **)profile)
  464.         != SA_SUCCEED)
  465.     {
  466.         (SA_VOID)free(profile);
  467.         sa_log2(sactx, SA_LOG_ERROR,
  468.             "sa_conn_key(SET, LOGIN_PROFILE_KEY) failed!");
  469.         return (SA_FAIL);
  470.     }
  471.  
  472. #ifdef DEBUG
  473.     (SA_VOID)sa_conn_props(saconn, SA_GET, SA_CONNPROP_HOST, name, 60,
  474.         &namelen);
  475.     name[namelen] = '\0';
  476.     sprintf(buffer, "%sUser '%s' logged in [host %s]", 
  477.         (radiusauth ? "Radius " : (sqlauth ? "SQL " : (ntauth ? "NT " : ""))), 
  478.         username, name);
  479.     sa_log2(sactx, SA_LOG_TRACE, buffer);
  480. #endif
  481.  
  482.     return (SA_SUCCEED);
  483. }
  484.  
  485. /*
  486. **  USER_LOGOUT
  487. **
  488. **    Log out a user.  Free profile resources.
  489. **
  490. **  Parameters:
  491. **    sactx        Sambar Server Application context to release.
  492. **    saconn        Sambar Server User Connection handle.
  493. **
  494. **  Return Values:
  495. **    SA_SUCCESS | SA_FAIL
  496. */
  497. SA_RETCODE SA_PUBLIC
  498. user_logout(sactx, saconn)
  499. SA_CTX        *sactx;
  500. SA_CONN        *saconn;
  501. {
  502.     SA_VOID            *entry;
  503.     LOGIN_PROFILE    *profile;
  504. #ifdef DEBUG
  505.     SA_CHAR            buffer[512];
  506. #endif
  507.  
  508.     /* Get the user's handle from the profile context                    */
  509.     if (sa_conn_key(saconn, SA_GET, LOGIN_PROFILE_KEY, (SA_VOID **)&profile)
  510.         != SA_SUCCEED)
  511.     {
  512.         /* User never completed login                                    */
  513.         return (SA_SUCCEED);
  514.     }
  515.  
  516.     /* Clear the user's profile handle                                    */
  517.     (SA_VOID)sa_conn_key(saconn, SA_CLEAR, LOGIN_PROFILE_KEY, &entry);
  518.  
  519. #ifdef DEBUG
  520.     sprintf(buffer, "User '%s' logged out.", profile->username);
  521.     sa_log2(sactx, SA_LOG_TRACE, buffer);
  522. #endif
  523.  
  524.     if (profile->data != (SA_PROFILE *)NULL)
  525.     {
  526.         (SA_VOID)sa_profile_save(sactx, profile->data);
  527.         (SA_VOID)sa_profile_exit(sactx, profile->data);
  528.     }
  529.  
  530.     (void)free(profile);
  531.  
  532.     return (SA_SUCCEED);
  533. }
  534.  
  535. /*
  536. **  USER_PROFILE
  537. **
  538. **    Respond to a user profile request.
  539. **
  540. **  Parameters:
  541. **    sactx        Sambar Server Application context to release.
  542. **    saconn        Sambar Server User Connection handle.
  543. **    buffer        Profile attribute being queried.
  544. **    buflen        Length of the profile attribute.
  545. **    data        Buffer for the profile result 
  546. **                Note: A maximum of 512 bytes may be written to the data buffer.
  547. **
  548. **  Return Values:
  549. **    SA_SUCCESS | SA_FAIL
  550. */
  551. SA_RETCODE SA_PUBLIC
  552. user_profile(sactx, saconn, action, name, namelen, datap)
  553. SA_CTX        *sactx;
  554. SA_CONN        *saconn;
  555. SA_INT        action;
  556. SA_CHAR        *name;
  557. SA_INT        namelen;
  558. SA_VOID        *datap;
  559. {
  560.     LOGIN_PROFILE    *profile;
  561.     SA_CHAR            tmp[512];
  562.  
  563.     /* Get the user's profile handle                                     */
  564.     if (sa_conn_key(saconn, SA_GET, LOGIN_PROFILE_KEY, (SA_VOID **)&profile)
  565.         != SA_SUCCEED)
  566.     {
  567.         /* User never completed login                                    */
  568.         return (SA_FAIL);
  569.     }
  570.  
  571.     if (profile == (LOGIN_PROFILE *)NULL)
  572.     {
  573.         sa_log2(sactx, SA_LOG_ERROR,
  574.             "user_profile:  LOGIN_PROFILE_KEY returned NULL!");
  575.         return (SA_FAIL);
  576.     }
  577.  
  578.     if (profile->data == (SA_PROFILE *)NULL)
  579.     {
  580.         sprintf(tmp, "user_profile:  SA_PROFILE returned NULL for user %s!",
  581.             profile->name);
  582.         sa_log2(sactx, SA_LOG_ERROR, tmp);
  583.         return (SA_FAIL);
  584.     }
  585.  
  586.     /* 
  587.     ** Profile lookup
  588.     */
  589.     if (action == SA_GET)
  590.     {
  591.         if ((namelen == 5) && (strncmp(name, "group", 5) == 0))
  592.         {
  593.             *((SA_CHAR **)datap) = profile->group;
  594.         }
  595.         else if ((namelen == 4) && (strncmp(name, "name", 4) == 0))
  596.         {
  597.             *((SA_CHAR **)datap) = profile->name;
  598.         }
  599.         else if ((namelen == 8) && (strncmp(name, "username", 8) == 0))
  600.         {
  601.             *((SA_CHAR **)datap) = profile->username;
  602.         }
  603.         else if ((namelen == 3) && (strncmp(name, "dir", 3) == 0))
  604.         {
  605.             *((SA_CHAR **)datap) = profile->dir;
  606.         }
  607.         else if ((namelen == 6) && (strncmp(name, "davdir", 6) == 0))
  608.         {
  609.             *((SA_CHAR **)datap) = profile->davdir;
  610.         }
  611.         else
  612.         {
  613.             if (sa_profile_get(sactx, profile->data, name, namelen, 
  614.                 (SA_CHAR **)datap) != SA_SUCCEED)
  615.             {
  616. #ifdef    DEBUG
  617.                 sprintf(tmp, "Profile attribute '%s' not found!", name);
  618.                 sa_log2(sactx, SA_LOG_WARN, tmp);
  619. #endif    /* DEBUG */
  620.                 return (SA_FAIL);
  621.             }
  622.         }
  623.     }
  624.     else
  625.     {
  626.         if (sa_profile_set(sactx, profile->data, name, namelen, 
  627.             (SA_CHAR *)datap) != SA_SUCCEED)
  628.         {
  629.             sprintf(tmp, "Profile attribute '%s' could not be set!", name);
  630.             sa_log2(sactx, SA_LOG_WARN, tmp);
  631.             return (SA_FAIL);
  632.         }
  633.     }
  634.  
  635.     return (SA_SUCCEED);
  636. }
  637.  
  638. /*
  639. **  USER_ADD
  640. **
  641. **    Add a new user
  642. **
  643. **  Parameters:
  644. **    sactx        Sambar Server context
  645. **    saconn        Sambar Server connection
  646. **    saparams    RPC Parameters
  647. **    infop        Error parameters
  648. **
  649. **  Returns:
  650. **    SA_SUCCEED | SA_FAIL
  651. */
  652. SA_RETCODE SA_PUBLIC
  653. user_add(sactx, saconn, saparams, infop)
  654. SA_CTX        *sactx;
  655. SA_CONN        *saconn;
  656. SA_PARAMS    *saparams;
  657. SA_INT        *infop;
  658. {
  659.     SA_INT        mbox;
  660.     SA_INT        datalen;
  661.     SA_INT        makedir;
  662.     SA_CHAR        *data;
  663.     SA_CHAR        path[1024];
  664.     SA_PASSWD    passwd;
  665.     SA_PASSWD    tmppasswd;
  666.  
  667.     memset(&passwd, 0, sizeof(SA_PASSWD));
  668.     
  669.     mbox = 0;
  670.     if (sa_param(sactx, saparams, "mbox", &data, &datalen) == SA_SUCCEED)
  671.     {
  672.         if ((datalen == 2) && (stricmp(data, "on") == 0))
  673.             mbox = 1;
  674.     }
  675.     
  676.     if (sa_param(sactx, saparams, "password", &data, &datalen) != SA_SUCCEED)
  677.     {
  678.         *infop = SA_E_INVALIDDATA;
  679.         sa_log2(sactx, SA_LOG_WARN, 
  680.             "user_add(): Expected parameter 'password'!");
  681.         return (SA_FAIL);
  682.     }
  683.     
  684.     passwd.passwordlen = MIN(datalen, SA_MAX_NAME);
  685.     if (passwd.passwordlen > 0)
  686.         memcpy(passwd.password, data, passwd.passwordlen);
  687.  
  688.     if (sa_param(sactx, saparams, "group", &data, &datalen) != SA_SUCCEED)
  689.     {
  690.         *infop = SA_E_INVALIDDATA;
  691.         sa_log2(sactx, SA_LOG_WARN, "user_add(): Expected parameter 'group'!");
  692.         return (SA_FAIL);
  693.     }
  694.     
  695.     passwd.grouplen = MIN(datalen, SA_MAX_NAME);
  696.     if (passwd.grouplen > 0)
  697.         memcpy(passwd.group, data, passwd.grouplen);
  698.  
  699.     if (sa_param(sactx, saparams, "name", &data, &datalen) != SA_SUCCEED)
  700.     {
  701.         *infop = SA_E_INVALIDDATA;
  702.         sa_log2(sactx, SA_LOG_WARN, "user_add(): Expected parameter 'name'!");
  703.         return (SA_FAIL);
  704.     }
  705.     
  706.     passwd.namelen = MIN(datalen, SA_MAX_NAME);
  707.     if (passwd.namelen > 0)
  708.         memcpy(passwd.name, data, passwd.namelen);
  709.  
  710.     makedir = 0;
  711.     if (sa_param(sactx, saparams, "makedir", &data, &datalen) == SA_SUCCEED)
  712.     {
  713.         if ((datalen == 4) && (strcmp(data, "true") == 0))
  714.             makedir = 1;
  715.     }
  716.  
  717.     if (sa_param(sactx, saparams, "dir", &data, &datalen) != SA_SUCCEED)
  718.     {
  719.         *infop = SA_E_INVALIDDATA;
  720.         sa_log2(sactx, SA_LOG_WARN, "user_add(): Expected parameter 'dir'!");
  721.         return (SA_FAIL);
  722.     }
  723.     
  724.     passwd.dirlen = MIN(datalen, SA_MAX_NAME);
  725.     if (passwd.dirlen > 0)
  726.         memcpy(passwd.dir, data, passwd.dirlen);
  727.  
  728.     if (sa_param(sactx, saparams, "ftpprivs", &data, &datalen) != SA_SUCCEED)
  729.     {
  730.         *infop = SA_E_INVALIDDATA;
  731.         sa_log2(sactx, SA_LOG_WARN, 
  732.             "user_add(): Expected parameter 'ftpprivs'!");
  733.         return (SA_FAIL);
  734.     }
  735.  
  736.     if (datalen < 12)
  737.         passwd.privs = atol(data);
  738.     
  739.     if (sa_param(sactx, saparams, "ftpmax", &data, &datalen) != SA_SUCCEED)
  740.     {
  741.         *infop = SA_E_INVALIDDATA;
  742.         sa_log2(sactx, SA_LOG_WARN,
  743.             "user_add(): Expected parameter 'ftpmax'!");
  744.         return (SA_FAIL);
  745.     }
  746.     
  747.     if (datalen < 12)
  748.         passwd.ftpmax = atol(data);
  749.     if (passwd.ftpmax < 5)
  750.         passwd.ftpmax = 0;
  751.  
  752.     if (sa_param(sactx, saparams, "username", &data, &datalen) != SA_SUCCEED)
  753.     {
  754.         *infop = SA_E_INVALIDDATA;
  755.         sa_log2(sactx, SA_LOG_WARN,
  756.             "user_add(): Expected parameter 'username'!");
  757.         return (SA_FAIL);
  758.     }
  759.  
  760.     if ((datalen == 0) || (datalen > SA_MAX_NAME))
  761.     {
  762.         *infop = SA_E_INVALIDDATA;
  763.         sa_log2(sactx, SA_LOG_WARN, "user_add(): 'username' field left NULL!");
  764.         return (SA_FAIL);
  765.     }
  766.  
  767.     /* Does the user already exist?                                        */
  768.     if (sa_passwd_lookup(sactx, data, datalen, &tmppasswd) == SA_SUCCEED)
  769.     {
  770.         *infop = SA_E_ALREADYDEFINED;
  771.         return (SA_FAIL);
  772.     }
  773.  
  774.     /* Create the user account.                                            */
  775.     if (sa_passwd_add(sactx, data, datalen, &passwd) != SA_SUCCEED)
  776.     {
  777.         *infop = SA_E_INTERNALSYSTEM;
  778.         sa_log2(sactx, SA_LOG_ERROR, "user_add(): sa_passwd_add() failed!");
  779.         return (SA_FAIL);
  780.     }
  781.  
  782.     /* Create the user mailbox.                                            */
  783.     if (mbox)
  784.     {
  785.         if (sa_mbox_create(sactx, data) != SA_SUCCEED)
  786.         {
  787.             *infop = SA_E_ALREADYDEFINED;
  788.             sa_log2(sactx, SA_LOG_ERROR, "user_add(): sa_mbox_create() failed!");
  789.             return (SA_FAIL);
  790.         }
  791.     }
  792.  
  793.     /* Create the user directory                                        */
  794.     if ((makedir) && (passwd.dirlen > 0))
  795.     {
  796.         if (sa_get_userpath(sactx, saconn, passwd.dir, path, 1000) 
  797.             == SA_SUCCEED)
  798.         {
  799. #ifdef WIN32
  800.             (void)mkdir(path);
  801. #else
  802.             (void)mkdir(path, 733);
  803. #endif
  804.         }
  805.     }
  806.  
  807.     return (SA_SUCCEED);
  808. }
  809.  
  810. /*
  811. **  USER_UPDATE
  812. **
  813. **    Update an existing user
  814. **
  815. **  Parameters:
  816. **    sactx        Sambar Server context
  817. **    saconn        Sambar Server connection
  818. **    saparams    RPC Parameters
  819. **    infop        Error parameters
  820. **
  821. **  Returns:
  822. **    SA_SUCCEED | SA_FAIL
  823. */
  824. SA_RETCODE SA_PUBLIC
  825. user_update(sactx, saconn, saparams, infop)
  826. SA_CTX        *sactx;
  827. SA_CONN        *saconn;
  828. SA_PARAMS    *saparams;
  829. SA_INT        *infop;
  830. {
  831.     SA_INT        mbox;
  832.     SA_INT        datalen;
  833.     SA_INT        makedir;
  834.     SA_CHAR        *data;
  835.     SA_CHAR        path[1024];
  836.     SA_PASSWD    passwd;
  837.  
  838.     memset(&passwd, 0, sizeof(SA_PASSWD));
  839.  
  840.     mbox = 0;
  841.     if (sa_param(sactx, saparams, "mbox", &data, &datalen) == SA_SUCCEED)
  842.     {
  843.         if ((datalen == 2) && (stricmp(data, "on") == 0))
  844.             mbox = 1;
  845.     }
  846.     
  847.     if (sa_param(sactx, saparams, "password", &data, &datalen) != SA_SUCCEED)
  848.     {
  849.         *infop = SA_E_INVALIDDATA;
  850.         sa_log2(sactx, SA_LOG_WARN,
  851.             "user_update(): Expected parameter 'password'!");
  852.         return (SA_FAIL);
  853.     }
  854.     
  855.     passwd.passwordlen = MIN(datalen, SA_MAX_NAME);
  856.     if (passwd.passwordlen > 0)
  857.         memcpy(passwd.password, data, passwd.passwordlen);
  858.  
  859.     if (sa_param(sactx, saparams, "group", &data, &datalen) != SA_SUCCEED)
  860.     {
  861.         *infop = SA_E_INVALIDDATA;
  862.         sa_log2(sactx, SA_LOG_WARN,
  863.             "user_update(): Expected parameter 'group'!");
  864.         return (SA_FAIL);
  865.     }
  866.     
  867.     passwd.grouplen = MIN(datalen, SA_MAX_NAME);
  868.     if (passwd.grouplen > 0)
  869.         memcpy(passwd.group, data, passwd.grouplen);
  870.  
  871.     if (sa_param(sactx, saparams, "name", &data, &datalen) != SA_SUCCEED)
  872.     {
  873.         *infop = SA_E_INVALIDDATA;
  874.         sa_log2(sactx, SA_LOG_WARN, "user_update(): Expected parameter 'name'!");
  875.         return (SA_FAIL);
  876.     }
  877.     
  878.     passwd.namelen = MIN(datalen, SA_MAX_NAME);
  879.     if (passwd.namelen > 0)
  880.         memcpy(passwd.name, data, passwd.namelen);
  881.  
  882.     makedir = 0;
  883.     if (sa_param(sactx, saparams, "makedir", &data, &datalen) == SA_SUCCEED)
  884.     {
  885.         if ((datalen == 4) && (strcmp(data, "true") == 0))
  886.             makedir = 1;
  887.     }
  888.  
  889.     if (sa_param(sactx, saparams, "dir", &data, &datalen) != SA_SUCCEED)
  890.     {
  891.         *infop = SA_E_INVALIDDATA;
  892.         sa_log2(sactx, SA_LOG_WARN, "user_update(): Expected parameter 'dir'!");
  893.         return (SA_FAIL);
  894.     }
  895.     
  896.     passwd.dirlen = MIN(datalen, SA_MAX_NAME);
  897.     if (passwd.dirlen > 0)
  898.         memcpy(passwd.dir, data, passwd.dirlen);
  899.  
  900.     if (sa_param(sactx, saparams, "ftpprivs", &data, &datalen) != SA_SUCCEED)
  901.     {
  902.         *infop = SA_E_INVALIDDATA;
  903.         sa_log2(sactx, SA_LOG_WARN, 
  904.             "user_update(): Expected parameter 'ftpprivs'!");
  905.         return (SA_FAIL);
  906.     }
  907.     
  908.     if (datalen < 12)
  909.         passwd.privs = atol(data);
  910.  
  911.     if (sa_param(sactx, saparams, "ftpmax", &data, &datalen) != SA_SUCCEED)
  912.     {
  913.         *infop = SA_E_INVALIDDATA;
  914.         sa_log2(sactx, SA_LOG_WARN, 
  915.             "user_update(): Expected parameter 'ftpmax'!");
  916.         return (SA_FAIL);
  917.     }
  918.     
  919.     if (datalen < 12)
  920.         passwd.ftpmax = atol(data);
  921.     if (passwd.ftpmax < 5)
  922.         passwd.ftpmax = 0;
  923.  
  924.     if (sa_param(sactx, saparams, "username", &data, &datalen) != SA_SUCCEED)
  925.     {
  926.         *infop = SA_E_INVALIDDATA;
  927.         sa_log2(sactx, SA_LOG_WARN, 
  928.             "user_update(): Expected parameter 'username'!");
  929.         return (SA_FAIL);
  930.     }
  931.  
  932.     if ((datalen == 0) || (datalen > SA_MAX_NAME))
  933.     {
  934.         *infop = SA_E_INVALIDDATA;
  935.         sa_log2(sactx, SA_LOG_WARN, 
  936.             "user_update(): 'username' field left NULL!");
  937.         return (SA_FAIL);
  938.     }
  939.  
  940.     if (sa_passwd_update(sactx, data, datalen, &passwd) != SA_SUCCEED)
  941.     {
  942.         *infop = SA_E_ALREADYDEFINED;
  943.         sa_log2(sactx, SA_LOG_ERROR, 
  944.             "user_update(): sa_passwd_update() failed!");
  945.         return (SA_FAIL);
  946.     }
  947.  
  948.     /* Create the user mailbox.                                            */
  949.     if (mbox)
  950.     {
  951.         if (sa_mbox_create(sactx, data) != SA_SUCCEED)
  952.         {
  953.             *infop = SA_E_ALREADYDEFINED;
  954.             sa_log2(sactx, SA_LOG_ERROR,
  955.                 "user_update(): sa_mbox_create() failed!");
  956.             return (SA_FAIL);
  957.         }
  958.     }
  959.  
  960.     /* Create the user directory                                        */
  961.     if ((makedir) && (passwd.dirlen > 0))
  962.     {
  963.         if (sa_get_userpath(sactx, saconn, passwd.dir, path, 1000) 
  964.             == SA_SUCCEED)
  965.         {
  966. #ifdef WIN32
  967.             (void)mkdir(path);
  968. #else
  969.             (void)mkdir(path, 733);
  970. #endif
  971.         }
  972.     }
  973.  
  974.     return (SA_SUCCEED);
  975. }
  976.  
  977. /*
  978. **  USER_DELETE
  979. **
  980. **    Delete an existing user
  981. **
  982. **  Parameters:
  983. **    sactx        Sambar Server context
  984. **    saconn        Sambar Server connection
  985. **    saparams    RPC Parameters
  986. **    infop        Error parameters
  987. **
  988. **  Returns:
  989. **    SA_SUCCEED | SA_FAIL
  990. */
  991. SA_RETCODE SA_PUBLIC
  992. user_delete(sactx, saconn, saparams, infop)
  993. SA_CTX        *sactx;
  994. SA_CONN        *saconn;
  995. SA_PARAMS    *saparams;
  996. SA_INT        *infop;
  997. {
  998.     SA_INT        datalen;
  999.     SA_INT        sysadminlen;
  1000.     SA_CHAR        *data;
  1001.     SA_CHAR        sysadmin[1024];
  1002.  
  1003.     /* Get the sysadmin user (disallow deletes)                            */
  1004.     if (sa_ctx_props(sactx, SA_GET, SA_CTXPROP_SYSADMIN, (SA_BYTE *)sysadmin,
  1005.         1000, &sysadminlen) != SA_SUCCEED)
  1006.     {
  1007.         sa_log2(sactx, SA_LOG_ERROR,
  1008.             "user_delete(): failure retrieving system admin user!");
  1009.         return (SA_FAIL);
  1010.     }
  1011.  
  1012.     if (sa_param(sactx, saparams, "username", &data, &datalen) != SA_SUCCEED)
  1013.     {
  1014.         *infop = SA_E_INVALIDDATA;
  1015.         sa_log2(sactx, SA_LOG_WARN,
  1016.             "user_delete(): Expected parameter 'username'!");
  1017.         return (SA_FAIL);
  1018.     }
  1019.  
  1020.     if ((datalen == 0) || (datalen > SA_MAX_NAME))
  1021.     {
  1022.         *infop = SA_E_INVALIDDATA;
  1023.         sa_log2(sactx, SA_LOG_WARN,
  1024.             "user_delete(): 'username' field left NULL!");
  1025.         return (SA_FAIL);
  1026.     }
  1027.  
  1028.     /* Don't allow the deletion of the system administrator                */
  1029.     if (!user__inlist(data, datalen, sysadmin, sysadminlen))
  1030.     {
  1031.         (SA_VOID)sa_passwd_delete(sactx, data, datalen);
  1032.         (SA_VOID)sa_mbox_delete(sactx, data);
  1033.         (SA_VOID)sa_mlist_delete(sactx, data);
  1034.     }
  1035.  
  1036.     return (SA_SUCCEED);
  1037. }
  1038.  
  1039. /*
  1040. **  USER_SELECT
  1041. **
  1042. **    List all users for selection.
  1043. **
  1044. **  Parameters:
  1045. **    sactx        Sambar Server context
  1046. **    saconn        Sambar Server connection
  1047. **    saparams    RPC Parameters
  1048. **    infop        Error parameters
  1049. **
  1050. **  Returns:
  1051. **    SA_SUCCEED | SA_FAIL
  1052. **
  1053. **  Notes:
  1054. **    This list is truncated at 500 names.
  1055. */
  1056. SA_RETCODE SA_PUBLIC
  1057. user_select(sactx, saconn, saparams, infop)
  1058. SA_CTX        *sactx;
  1059. SA_CONN        *saconn;
  1060. SA_PARAMS    *saparams;
  1061. SA_INT        *infop;
  1062. {
  1063.     SA_INT            i;
  1064.     SA_BOOL            selected;
  1065.     SA_INT            usernamelen;
  1066.     SA_INT            numusers;
  1067.     SA_CHAR            *username;
  1068.     SA_USER            users[500];
  1069.     SA_CHAR            buffer[512];
  1070.  
  1071.     /* If a username is provided make it SELECTED in the OPTION list    */
  1072.     (SA_VOID)sa_param(sactx, saparams, "username", &username, &usernamelen);
  1073.  
  1074.     if (sa_passwd_list(sactx, users, 500, &numusers) != SA_SUCCEED)
  1075.     {
  1076.         sa_log2(sactx, SA_LOG_ERROR,
  1077.             "user_select(): failure retrieving names list!");
  1078.         return (SA_FAIL);
  1079.     }
  1080.  
  1081.     /* Display the list of users.                                        */
  1082.     for (i = 0; i < numusers; i++)
  1083.     {
  1084.         selected = 0;
  1085.         if ((users[i].usernamelen == usernamelen) &&
  1086.             (memcmp(username, users[i].username, usernamelen) == 0))
  1087.         {
  1088.             selected = 1;
  1089.         }
  1090.  
  1091.         sprintf(buffer, "<OPTION %s>%s\n", (selected ? "SELECTED" : ""),
  1092.                 users[i].username);
  1093.  
  1094.         if (sa_conn_send(saconn, buffer, SA_NULLTERM) != SA_SUCCEED)
  1095.             return (SA_FAIL);
  1096.     }
  1097.  
  1098.     return (SA_SUCCEED);
  1099. }
  1100.  
  1101. /*
  1102. **  USER_LIST
  1103. **
  1104. **    List all users for delete or update.
  1105. **
  1106. **  Parameters:
  1107. **    sactx        Sambar Server context
  1108. **    saconn        Sambar Server connection
  1109. **    saparams    RPC Parameters
  1110. **    infop        Error parameters
  1111. **
  1112. **  Returns:
  1113. **    SA_SUCCEED | SA_FAIL
  1114. **
  1115. **  Notes:
  1116. **    This list is truncated at 500 names.
  1117. **    List users by group...
  1118. */
  1119. SA_RETCODE SA_PUBLIC
  1120. user_list(sactx, saconn, saparams, infop)
  1121. SA_CTX        *sactx;
  1122. SA_CONN        *saconn;
  1123. SA_PARAMS    *saparams;
  1124. SA_INT        *infop;
  1125. {
  1126.     SA_INT            i;
  1127.     SA_INT            j;
  1128.     SA_INT            sysadminlen;
  1129.     SA_INT            numusers;
  1130.     SA_INT            numgroups;
  1131.     SA_GROUP        groups[100];
  1132.     SA_USER            users[500];
  1133.     SA_CHAR            sysadmin[1024];
  1134.     SA_CHAR            buffer[512];
  1135.  
  1136.     /* Get the sysadmin user (disallow deletes)                            */
  1137.     if (sa_ctx_props(sactx, SA_GET, SA_CTXPROP_SYSADMIN, (SA_BYTE *)sysadmin,
  1138.         1000, &sysadminlen) != SA_SUCCEED)
  1139.     {
  1140.         sa_log2(sactx, SA_LOG_ERROR,
  1141.             "user_list(): failure retrieving system admin user!");
  1142.         return (SA_FAIL);
  1143.     }
  1144.  
  1145.     if (sa_passwd_list(sactx, users, 500, &numusers) != SA_SUCCEED)
  1146.     {
  1147.         sa_log2(sactx, SA_LOG_ERROR,
  1148.             "user_list(): failure retrieving names list!");
  1149.         return (SA_FAIL);
  1150.     }
  1151.  
  1152.     if (sa_group_list(sactx, groups, 100, &numgroups) != SA_SUCCEED)
  1153.     {
  1154.         sa_log2(sactx, SA_LOG_ERROR,
  1155.             "user_list(): failure retrieving groups list!");
  1156.         return (SA_FAIL);
  1157.     }
  1158.  
  1159.     /*
  1160.     ** Display the users by "group".
  1161.     ** Zero the usernamelen after displaying so we can put the rest in
  1162.     ** the "other" list.
  1163.     */
  1164.     for (j = 0; j < numgroups; j++)
  1165.     {
  1166.         sprintf(buffer, "<FONT SIZE=+1 COLOR=#990033>%s</FONT><BLOCKQUOTE>\n",
  1167.             groups[j].name);
  1168.         if (sa_conn_send(saconn, buffer, SA_NULLTERM) != SA_SUCCEED)
  1169.             return (SA_FAIL);
  1170.         
  1171.         /* Display the users in that group.                                */
  1172.         for (i = 0; i < numusers; i++)
  1173.         {
  1174.             if ((users[i].usernamelen > 0) && 
  1175.                 (users[i].grouplen == groups[j].namelen) &&
  1176.                 (memcmp(users[i].group, groups[j].name, users[i].grouplen)==0))
  1177.             {
  1178.                 /* Make sure we don't display the user twice.            */
  1179.                 users[i].usernamelen = 0;
  1180.  
  1181.                 if (!user__inlist(users[i].username, users[i].usernamelen, 
  1182.                     sysadmin, sysadminlen))
  1183.                 {
  1184.                     sprintf(buffer, 
  1185.                         "<A HREF=\"/session/deluser?username=%s&RCpage=/sysadmin/usermgmt/userlist.stm\" onClick=\"return confirmDelete()\"><IMG border=0 HEIGHT=20 WIDTH=20 SRC=\"/sysimage/system/trash.gif\"></A>\n",
  1186.                         users[i].username);
  1187.  
  1188.                     if (sa_conn_send(saconn, buffer, SA_NULLTERM) != SA_SUCCEED)
  1189.                         return (SA_FAIL);
  1190.                 }
  1191.  
  1192.                 sprintf(buffer, 
  1193.                     "<A HREF=\"/sysadmin/usermgmt/upduser.stm?RCSusername=%s\" TARGET=body><IMG border=0 HEIGHT=20 WIDTH=20 SRC=\"/sysimage/system/info.gif\"> %s</A><BR>\n",
  1194.                     users[i].username, users[i].username);
  1195.  
  1196.                 if (sa_conn_send(saconn, buffer, SA_NULLTERM) != SA_SUCCEED)
  1197.                     return (SA_FAIL);
  1198.             }
  1199.         }
  1200.  
  1201.         if (sa_conn_send(saconn, "</BLOCKQUOTE>", SA_NULLTERM) != SA_SUCCEED)
  1202.             return (SA_FAIL);
  1203.     }
  1204.  
  1205.     /* Display the "other" group                                        */
  1206.     sprintf(buffer, "<FONT SIZE=+1 COLOR=#990066>%s</FONT><BLOCKQUOTE>\n", 
  1207.         SA_DEFAULT_GROUP);
  1208.     if (sa_conn_send(saconn, buffer, SA_NULLTERM) != SA_SUCCEED)
  1209.         return (SA_FAIL);
  1210.         
  1211.     /* Display the users in that group.                                    */
  1212.     for (i = 0; i < numusers; i++)
  1213.     {
  1214.         /* Display all users not in any other group.                    */
  1215.         if (users[i].usernamelen > 0)
  1216.         {
  1217.             if (!user__inlist(users[i].username, users[i].usernamelen, 
  1218.                 sysadmin, sysadminlen))
  1219.             {
  1220.                 sprintf(buffer, 
  1221.                     "<A HREF=\"/session/deluser?username=%s&RCpage=/sysadmin/usermgmt/userlist.stm\" onClick=\"return confirmDelete()\"><IMG border=0 HEIGHT=15 WIDTH=15 SRC=\"/sysimage/system/trash.gif\"></A>\n",
  1222.                     users[i].username);
  1223.  
  1224.                 if (sa_conn_send(saconn, buffer, SA_NULLTERM) != SA_SUCCEED)
  1225.                     return (SA_FAIL);
  1226.             }
  1227.  
  1228.             sprintf(buffer, 
  1229.                 "<A HREF=\"/sysadmin/usermgmt/upduser.stm?RCSusername=%s\" TARGET=body><IMG border=0 HEIGHT=15 WIDTH=15 SRC=\"/sysimage/system/info.gif\"> %s</A><BR>\n",
  1230.                 users[i].username, users[i].username);
  1231.  
  1232.             if (sa_conn_send(saconn, buffer, SA_NULLTERM) != SA_SUCCEED)
  1233.                 return (SA_FAIL);
  1234.         }
  1235.  
  1236.     }
  1237.  
  1238.     if (sa_conn_send(saconn, "</BLOCKQUOTE>\n", SA_NULLTERM) != SA_SUCCEED)
  1239.         return (SA_FAIL);
  1240.  
  1241.     return (SA_SUCCEED);
  1242. }
  1243.  
  1244. /*
  1245. **  USER_PASSWD
  1246. **
  1247. **    Update a user' password.
  1248. **
  1249. **  Parameters:
  1250. **    sactx        Sambar Server context
  1251. **    saconn        Sambar Server connection
  1252. **    saparams    RPC Parameters
  1253. **    infop        Error parameters
  1254. **
  1255. **  Returns:
  1256. **    SA_SUCCEED | SA_FAIL
  1257. */
  1258. SA_RETCODE SA_PUBLIC
  1259. user_passwd(sactx, saconn, saparams, infop)
  1260. SA_CTX        *sactx;
  1261. SA_CONN        *saconn;
  1262. SA_PARAMS    *saparams;
  1263. SA_INT        *infop;
  1264. {
  1265.     SA_INT        datalen;
  1266.     SA_INT        passwordlen;
  1267.     SA_INT        usernamelen;
  1268.     SA_CHAR        *data;
  1269.     SA_CHAR        *password;
  1270.     SA_CHAR        *username;
  1271.     SA_PASSWD    passwd;
  1272.  
  1273.     /* What username is being updated?                                    */
  1274.     if (sa_param(sactx, saparams, "username", &username, &usernamelen) 
  1275.         != SA_SUCCEED)
  1276.     {
  1277.         *infop = SA_E_INVALIDDATA;
  1278.         sa_log2(sactx, SA_LOG_WARN,
  1279.             "user_passwd(): Expected parameter 'username'!");
  1280.         return (SA_FAIL);
  1281.     }
  1282.  
  1283.     if ((usernamelen == 0) || (usernamelen > SA_MAX_NAME))
  1284.     {
  1285.         *infop = SA_E_INVALIDDATA;
  1286.         sa_log2(sactx, SA_LOG_WARN,
  1287.             "user_update(): 'username' field left NULL!");
  1288.         return (SA_FAIL);
  1289.     }
  1290.  
  1291.     /* Lookup the username provided for update.                            */
  1292.     if (sa_passwd_lookup(sactx, username, usernamelen, &passwd) != SA_SUCCEED)
  1293.     {
  1294.         *infop = SA_E_INVALIDDATA;
  1295.         sa_log2(sactx, SA_LOG_ERROR,
  1296.             "user_passwd(): sa_passwd_lookup() failed!");
  1297.         return (SA_FAIL);
  1298.     }
  1299.  
  1300.     /* Make sure that the password is valid.                        */
  1301.     if (sa_param(sactx, saparams, "password", &data, &datalen) != SA_SUCCEED)
  1302.     {
  1303.         *infop = SA_E_INVALIDDATA;
  1304.         sa_log2(sactx, SA_LOG_WARN,
  1305.             "user_passwd(): Expected parameter 'password'!");
  1306.         return (SA_FAIL);
  1307.     }
  1308.     
  1309.     /* Compare with the existing password.                            */
  1310.     if (datalen != passwd.passwordlen)
  1311.     {    
  1312.         *infop = SA_E_INVALIDDATA;
  1313.         sa_log2(sactx, SA_LOG_WARN,
  1314.             "user_passwd(): Invalid password provided.");
  1315.         return (SA_FAIL);
  1316.     }
  1317.     
  1318.     if (datalen > 0)
  1319.     {
  1320.         if (memcmp(passwd.password, data, datalen) != 0)
  1321.         {
  1322.             *infop = SA_E_INVALIDDATA;
  1323.             sa_log2(sactx, SA_LOG_WARN,
  1324.                 "user_passwd(): Invalid password provided.");
  1325.             return (SA_FAIL);
  1326.         }
  1327.     }
  1328.  
  1329.     /* Get the new password.                                            */
  1330.     if (sa_param(sactx, saparams, "newpasswd", &password, &passwordlen) 
  1331.         != SA_SUCCEED)
  1332.     {
  1333.         *infop = SA_E_INVALIDDATA;
  1334.         sa_log2(sactx, SA_LOG_WARN,
  1335.             "user_passwd(): Expected parameter 'newpasswd'!");
  1336.         return (SA_FAIL);
  1337.     }
  1338.     
  1339.     /* Confirm the new password.                                        */
  1340.     if (sa_param(sactx, saparams, "confpasswd", &data, &datalen) 
  1341.         != SA_SUCCEED)
  1342.     {
  1343.         *infop = SA_E_INVALIDDATA;
  1344.         sa_log2(sactx, SA_LOG_WARN,
  1345.             "user_passwd(): Expected parameter 'confpasswd'!");
  1346.         return (SA_FAIL);
  1347.     }
  1348.  
  1349.     /* Does the new password and confirm password match?                */
  1350.     if ((passwordlen > 0) && (datalen > 0))
  1351.     {
  1352.         if ((passwordlen != datalen) ||
  1353.             (memcmp(password, data, datalen) != 0))
  1354.         {
  1355.             *infop = SA_E_INVALIDDATA;
  1356.             sa_log2(sactx, SA_LOG_WARN,
  1357.                 "user_passwd(): New & confirmation password do not match!");
  1358.             return (SA_FAIL);
  1359.         }
  1360.     }
  1361.     
  1362.     passwd.passwordlen = MIN(datalen, SA_MAX_NAME);
  1363.     if (passwd.passwordlen > 0)
  1364.         memcpy(passwd.password, data, passwd.passwordlen);
  1365.  
  1366.     if (sa_passwd_update(sactx, username, usernamelen, &passwd) != SA_SUCCEED)
  1367.     {
  1368.         sa_log2(sactx, SA_LOG_ERROR,
  1369.             "user_passwd(): sa_passwd_update() failed!");
  1370.         return (SA_FAIL);
  1371.     }
  1372.  
  1373.     return (SA_SUCCEED);
  1374. }
  1375.  
  1376. /*
  1377. **  USER_PROP
  1378. **
  1379. **    Lookup and return a single user property.
  1380. **
  1381. **  Parameters:
  1382. **    sactx        Sambar Server context
  1383. **    saconn        Sambar Server connection
  1384. **    saparams    RPC Parameters
  1385. **    infop        Error parameters
  1386. **
  1387. **  Return Values:
  1388. **    SA_SUCCESS | SA_FAIL
  1389. */
  1390. SA_RETCODE SA_PUBLIC
  1391. user_prop(sactx, saconn, saparams, infop)
  1392. SA_CTX        *sactx;
  1393. SA_CONN        *saconn;
  1394. SA_PARAMS    *saparams;
  1395. SA_INT        *infop;
  1396. {
  1397.     SA_PASSWD            passwd;
  1398.     SA_INT                userlen;
  1399.     SA_CHAR                *user;
  1400.     SA_INT                proplen;
  1401.     SA_CHAR                *prop;
  1402.     SA_CHAR                buffer[512];
  1403.  
  1404.     /* Get the page to direct to for user update                        */
  1405.     if (sa_param(sactx, saparams, "username", &user, &userlen) != SA_SUCCEED)
  1406.     {
  1407.         *infop = SA_E_INVALIDDATA;
  1408.         sa_log2(sactx, SA_LOG_WARN,
  1409.             "user_prop(): Expected parameter 'username'!");
  1410.         return (SA_FAIL);
  1411.     }
  1412.  
  1413.     if ((userlen == 0) || (userlen > SA_MAX_NAME))
  1414.     {
  1415.         *infop = SA_E_INVALIDDATA;
  1416.         sa_log2(sactx, SA_LOG_WARN, "user_prop(): 'username' field left NULL!");
  1417.         return (SA_FAIL);
  1418.     }
  1419.  
  1420.     /* Get the property being looked up.                                */
  1421.     if (sa_param(sactx, saparams, "prop", &prop, &proplen) != SA_SUCCEED)
  1422.     {
  1423.         *infop = SA_E_INVALIDDATA;
  1424.         sa_log2(sactx, SA_LOG_WARN, "user_prop(): Expected parameter 'prop'!");
  1425.         return (SA_FAIL);
  1426.     }
  1427.  
  1428.     if ((proplen == 0) || (proplen > SA_MAX_NAME))
  1429.     {
  1430.         *infop = SA_E_INVALIDDATA;
  1431.         sa_log2(sactx, SA_LOG_WARN, "user_prop(): 'prop' field left NULL!");
  1432.         return (SA_FAIL);
  1433.     }
  1434.  
  1435.     if (sa_passwd_lookup(sactx, user, userlen, &passwd) != SA_SUCCEED)
  1436.     {
  1437.         sprintf(buffer, "User lookup for '%s' failed.", user);
  1438.         sa_log2(sactx, SA_LOG_WARN, buffer);
  1439.         *infop = SA_E_INVALIDDATA;
  1440.         return (SA_FAIL);
  1441.     }
  1442.  
  1443.     /* Lookup and return the appropriate property                        */
  1444.     if (strcmp(prop, "group") == 0)
  1445.     {
  1446.         if (sa_conn_send(saconn, passwd.group, passwd.grouplen) != SA_SUCCEED)
  1447.             return (SA_FAIL);
  1448.     }
  1449.     else if (strcmp(prop, "password") == 0)
  1450.     {
  1451.         if (sa_conn_send(saconn, passwd.password, passwd.passwordlen) 
  1452.             != SA_SUCCEED)
  1453.         {
  1454.             return (SA_FAIL);
  1455.         }
  1456.     }
  1457.     else if (strcmp(prop, "name") == 0)
  1458.     {
  1459.         if (sa_conn_send(saconn, passwd.name, passwd.namelen) != SA_SUCCEED)
  1460.             return (SA_FAIL);
  1461.     }
  1462.     else if (strcmp(prop, "dir") == 0)
  1463.     {
  1464.         if (sa_conn_send(saconn, passwd.dir, passwd.dirlen) != SA_SUCCEED)
  1465.             return (SA_FAIL);
  1466.     }
  1467.     else if (strcmp(prop, "ftpprivs") == 0)
  1468.     {
  1469.         if (sa_param(sactx, saparams, "checked", &prop, &proplen) == SA_SUCCEED)
  1470.         {
  1471.             int        tmp;
  1472.  
  1473.             tmp = 0;
  1474.             if (proplen > 0)
  1475.                 tmp = atoi(prop);
  1476.         
  1477.             if (tmp == passwd.privs)
  1478.             {
  1479.                 if (sa_conn_send(saconn, "CHECKED", SA_NULLTERM) != SA_SUCCEED)
  1480.                     return (SA_FAIL);
  1481.             }
  1482.         }
  1483.         else
  1484.         {
  1485.             sprintf(buffer, "%ld", passwd.privs);
  1486.             if (sa_conn_send(saconn, buffer, SA_NULLTERM) != SA_SUCCEED)
  1487.                 return (SA_FAIL);
  1488.         }
  1489.     }
  1490.     else if (strcmp(prop, "ftpmax") == 0)
  1491.     {
  1492.         if (passwd.ftpmax < 5)
  1493.             passwd.ftpmax = 0;
  1494.         sprintf(buffer, "%ld", passwd.ftpmax);
  1495.         if (sa_conn_send(saconn, buffer, SA_NULLTERM) != SA_SUCCEED)
  1496.             return (SA_FAIL);
  1497.     }
  1498.     else if (strcmp(prop, "mbox") == 0)
  1499.     {
  1500.         if (sa_mbox_exists(sactx, user))
  1501.             strcpy(buffer, "CHECKED");
  1502.         else
  1503.             strcpy(buffer, "");
  1504.         if (sa_conn_send(saconn, buffer, SA_NULLTERM) != SA_SUCCEED)
  1505.             return (SA_FAIL);
  1506.     }
  1507.     else 
  1508.     {
  1509.         sprintf(buffer, "User lookup for property '%s' failed.", prop);
  1510.         sa_log2(sactx, SA_LOG_WARN, buffer);
  1511.         *infop = SA_E_INVALIDDATA;
  1512.         return (SA_FAIL);
  1513.     }
  1514.  
  1515.     return (SA_SUCCEED);
  1516. }
  1517.  
  1518. /*
  1519. **  USER_MAILLIST
  1520. **
  1521. **    List all mail users for delete or update.
  1522. **
  1523. **  Parameters:
  1524. **    sactx        Sambar Server context
  1525. **    saconn        Sambar Server connection
  1526. **    saparams    RPC Parameters
  1527. **    infop        Error parameters
  1528. **
  1529. **  Returns:
  1530. **    SA_SUCCEED | SA_FAIL
  1531. **
  1532. **  Notes:
  1533. **    This list is truncated at 500 names.
  1534. */
  1535. SA_RETCODE SA_PUBLIC
  1536. user_maillist(sactx, saconn, saparams, infop)
  1537. SA_CTX        *sactx;
  1538. SA_CONN        *saconn;
  1539. SA_PARAMS    *saparams;
  1540. SA_INT        *infop;
  1541. {
  1542.     SA_INT            i;
  1543.     SA_INT            numusers;
  1544.     SA_USER            users[500];
  1545.     SA_CHAR            buffer[512];
  1546.     SA_MBOXINFO        info;
  1547.  
  1548.     if (sa_passwd_list(sactx, users, 500, &numusers) != SA_SUCCEED)
  1549.     {
  1550.         sa_log2(sactx, SA_LOG_ERROR,
  1551.             "user_list(): failure retrieving names list!");
  1552.         return (SA_FAIL);
  1553.     }
  1554.  
  1555.     if (sa_conn_send(saconn, "<TABLE BORDER=0 CELLPADDING=2>\n", SA_NULLTERM) 
  1556.         != SA_SUCCEED)
  1557.     {
  1558.         return (SA_FAIL);
  1559.     }
  1560.  
  1561.     if (sa_conn_send(saconn, 
  1562.         "<TR nowrap><TH>User</TH><TH>Mailbox</TH><TH>Folders</TH><TH nowrap>Read / Unread</TH><TH>Digest</TH></TR>\n",
  1563.         SA_NULLTERM) != SA_SUCCEED)
  1564.     {
  1565.         return (SA_FAIL);
  1566.     }
  1567.  
  1568.     /*
  1569.     ** Display the mail users
  1570.     */
  1571.     for (i = 0; i < numusers; i++)
  1572.     {
  1573.         sprintf(buffer, "<TR nowrap><TD><b>%s</b> </TD><TD>", 
  1574.             users[i].username);
  1575.         if (sa_conn_send(saconn, buffer, SA_NULLTERM) != SA_SUCCEED)
  1576.             return (SA_FAIL);
  1577.  
  1578.         if (sa_mbox_exists(sactx, users[i].username))
  1579.         {
  1580.             sprintf(buffer, 
  1581.                 "<A HREF=\"/session/usermbox?action=delete&username=%s&RCpage=/sysadmin/mail/users.stm\"><font color=#990000>Delete</font></A></TD>",
  1582.                 users[i].username);
  1583.             if (sa_conn_send(saconn, buffer, SA_NULLTERM) != SA_SUCCEED)
  1584.                 return (SA_FAIL);
  1585.  
  1586.             (void)sa_mbox_info(sactx, users[i].username, &info);
  1587.  
  1588.             sprintf(buffer, "<TD>%d</TD><TD nowrap><font size=-1>", 
  1589.                 info.folders);
  1590.             if (sa_conn_send(saconn, buffer, SA_NULLTERM) != SA_SUCCEED)
  1591.                 return (SA_FAIL);
  1592.  
  1593.             if (info.readsize == 0)
  1594.                 strcpy(buffer, "0 bytes");
  1595.             else if (info.readsize < 1024)
  1596.                 strcpy(buffer, "1 KB");
  1597.             else if (info.readsize < 1024 * 1024)
  1598.                 sprintf(buffer, "%d KB", (int)(info.readsize / 1024));
  1599.             else
  1600.                 sprintf(buffer, "%d MB", (int)(info.readsize/(1024*1024)));
  1601.  
  1602.             if (sa_conn_send(saconn, buffer, SA_NULLTERM) != SA_SUCCEED)
  1603.                 return (SA_FAIL);
  1604.  
  1605.             if (info.unreadsize == 0)
  1606.                 strcpy(buffer, " / 0 bytes");
  1607.             else if (info.unreadsize < 1024)
  1608.                 strcpy(buffer, " / 1 KB");
  1609.             else if (info.unreadsize < 1024 * 1024)
  1610.                 sprintf(buffer," / %d KB",(int)(info.readsize / 1024));
  1611.             else
  1612.                 sprintf(buffer," / %d MB",(int)(info.readsize/(1024*1024)));
  1613.  
  1614.             if (sa_conn_send(saconn, buffer, SA_NULLTERM) != SA_SUCCEED)
  1615.                 return (SA_FAIL);
  1616.  
  1617.             if (sa_conn_send(saconn, "</font></TD><TD>", SA_NULLTERM) 
  1618.                 != SA_SUCCEED)
  1619.             {
  1620.                 return (SA_FAIL);
  1621.             }
  1622.  
  1623.             sprintf(buffer, 
  1624.                 "<A HREF=\"/sysadmin/mail/digest.stm?username=%s\"><I>Generate</I></A>",
  1625.                 users[i].username);
  1626.             if (sa_conn_send(saconn, buffer, SA_NULLTERM) != SA_SUCCEED)
  1627.                 return (SA_FAIL);
  1628.  
  1629.         }
  1630.         else
  1631.         {
  1632.             sprintf(buffer, 
  1633.                 "<A HREF=\"/session/usermbox?action=create&username=%s&RCpage=/sysadmin/mail/users.stm\"><font color=#009900>Create</font></A></TD><TD>", 
  1634.                 users[i].username);
  1635.             if (sa_conn_send(saconn, buffer, SA_NULLTERM) != SA_SUCCEED)
  1636.                 return (SA_FAIL);
  1637.         }
  1638.  
  1639.         if (sa_conn_send(saconn, "</TD></TR>\n", SA_NULLTERM) != SA_SUCCEED)
  1640.             return (SA_FAIL);
  1641.     }
  1642.  
  1643.     if (sa_conn_send(saconn, "</TABLE>\n", SA_NULLTERM) != SA_SUCCEED)
  1644.         return (SA_FAIL);
  1645.  
  1646.     return (SA_SUCCEED);
  1647. }
  1648.  
  1649. /*
  1650. **  USER_MBOX
  1651. **
  1652. **    Update an user mailbox
  1653. **
  1654. **  Parameters:
  1655. **    sactx        Sambar Server context
  1656. **    saconn        Sambar Server connection
  1657. **    saparams    RPC Parameters
  1658. **    infop        Error parameters
  1659. **
  1660. **  Returns:
  1661. **    SA_SUCCEED | SA_FAIL
  1662. */
  1663. SA_RETCODE SA_PUBLIC
  1664. user_mailbox(sactx, saconn, saparams, infop)
  1665. SA_CTX        *sactx;
  1666. SA_CONN        *saconn;
  1667. SA_PARAMS    *saparams;
  1668. SA_INT        *infop;
  1669. {
  1670.     SA_BOOL        create;
  1671.     SA_INT        datalen;
  1672.     SA_CHAR        *data;
  1673.     SA_PASSWD    passwd;
  1674.  
  1675.     if (sa_param(sactx, saparams, "action", &data, &datalen) != SA_SUCCEED)
  1676.     {
  1677.         *infop = SA_E_INVALIDDATA;
  1678.         sa_log2(sactx, SA_LOG_WARN,
  1679.             "user_mailbox(): Expected parameter 'action'!");
  1680.         return (SA_FAIL);
  1681.     }
  1682.  
  1683.     if (stricmp(data, "create") == 0)
  1684.     {
  1685.         create = 1;
  1686.     }
  1687.     else if (stricmp(data, "delete") == 0)
  1688.     {
  1689.         create = 0;
  1690.     }
  1691.     else
  1692.     {
  1693.         *infop = SA_E_INVALIDDATA;
  1694.         sa_log2(sactx, SA_LOG_WARN,
  1695.             "user_mailbox(): Parameter 'action' not create/delete!");
  1696.         return (SA_FAIL);
  1697.     }
  1698.     
  1699.     if ((sa_param(sactx, saparams, "username", &data, &datalen) != SA_SUCCEED)
  1700.         || (datalen == 0) || (datalen > SA_MAX_NAME))
  1701.     {
  1702.         *infop = SA_E_INVALIDDATA;
  1703.         sa_log2(sactx, SA_LOG_WARN,
  1704.             "user_mailbox(): Expected parameter 'username'!");
  1705.         return (SA_FAIL);
  1706.     }
  1707.  
  1708.     /* Verify the user account exists.                                    */
  1709.     if (sa_passwd_lookup(sactx, data, datalen, &passwd) == SA_SUCCEED)
  1710.     {
  1711.         /* Create the user mailbox.                                        */
  1712.         if (create)
  1713.         {
  1714.             if (sa_mbox_create(sactx, data) != SA_SUCCEED)
  1715.             {
  1716.                 sa_log2(sactx, SA_LOG_ERROR, 
  1717.                     "user_mailbox(): sa_mbox_create() failed!");
  1718.             }
  1719.         }
  1720.         else
  1721.         {
  1722.             if (sa_mbox_delete(sactx, data) != SA_SUCCEED)
  1723.             {
  1724.                 sa_log2(sactx, SA_LOG_ERROR, 
  1725.                     "user_mailbox(): sa_mbox_delete() failed!");
  1726.             }
  1727.         }
  1728.     }
  1729.     else
  1730.     {
  1731.         *infop = SA_E_INVALIDDATA;
  1732.         sa_log2(sactx, SA_LOG_ERROR,
  1733.             "user_mailbox(): Failure creating user mailbox; no login found!");
  1734.         return (SA_FAIL);
  1735.     }
  1736.  
  1737.     return (SA_SUCCEED);
  1738. }
  1739.  
  1740.  
  1741. /*
  1742. **  FTP_CONNECT
  1743. **
  1744. **    Process an FTP Connect request. Verify the username/password against 
  1745. **    the Sambar Server password interfaces and return the root directory
  1746. **    and priviledges.
  1747. **
  1748. **  Parameters:
  1749. **    sactx            Sambar Server Application context to release.
  1750. **    saconn            Sambar Server User Connection handle.
  1751. **    username        Name of the user logging in.
  1752. **    usernamelen        Length of the user name
  1753. **    password        Password of the user logging in.
  1754. **    passwordlen        Length of the password.
  1755. **    ftpresp            FTP response structure.
  1756. **
  1757. **  Return Values:
  1758. **    SA_SUCCESS         Login Accepted.
  1759. **    SA_FAIL            Login Denied.
  1760. */
  1761. SA_RETCODE SA_PUBLIC
  1762. ftp_connect(sactx, name, namelen, password, passwordlen, ftpresp)
  1763. SA_CTX        *sactx;
  1764. SA_CHAR        *name;
  1765. SA_INT        namelen;
  1766. SA_CHAR        *password;
  1767. SA_INT        passwordlen;
  1768. SA_FTP        *ftpresp;
  1769. {
  1770.     SA_BOOL            ntauth;
  1771.     SA_BOOL            sqlauth;
  1772.     SA_BOOL            radiusauth;
  1773.     SA_BOOL            usepasswd;
  1774.     SA_BOOL            status;
  1775.     SA_PASSWD        passwd;
  1776.     SA_CHAR            buffer[512];
  1777.  
  1778.     ntauth = 0;
  1779.     if (sa_ctx_props(sactx, SA_GET, SA_CTXPROP_NTAUTH, buffer, 30, 
  1780.         (SA_INT *)NULL) == SA_SUCCEED)
  1781.     {
  1782.         if (stricmp(buffer, "true") == 0)
  1783.             ntauth = 1;
  1784.     }
  1785.  
  1786.     radiusauth = 0;
  1787.     if (sa_ctx_props(sactx, SA_GET, SA_CTXPROP_RADIUSAUTH, buffer, 30, 
  1788.         (SA_INT *)NULL) == SA_SUCCEED)
  1789.     {
  1790.         if (stricmp(buffer, "true") == 0)
  1791.             radiusauth = 1;
  1792.     }
  1793.  
  1794.     sqlauth = 0;
  1795.     if (sa_ctx_props(sactx, SA_GET, SA_CTXPROP_SQLAUTH, buffer, 30, 
  1796.         (SA_INT *)NULL) == SA_SUCCEED)
  1797.     {
  1798.         if (stricmp(buffer, "true") == 0)
  1799.             sqlauth = 1;
  1800.     }
  1801.  
  1802.     usepasswd = 0;
  1803.     if ((ntauth) || (radiusauth))
  1804.     {
  1805.         if ((sa_passwd_verify(sactx, name, namelen, password, passwordlen,
  1806.             &status) != SA_SUCCEED) || (!status))
  1807.         {
  1808.             sprintf(buffer, 
  1809.                 "%sFTP login for user '%s' failed - bad password", 
  1810.                 (radiusauth ? "Radius " : (ntauth ? "NT " : "")), name);
  1811.             sa_log2(sactx, SA_LOG_WARN, buffer);
  1812.             return (SA_FAIL);
  1813.         }
  1814.  
  1815.         ftpresp->privs = SA_PRIV_READONLY;
  1816.         ftpresp->ftpmax = 0;
  1817.  
  1818.         if (sa_ctx_props(sactx, SA_GET, SA_CTXPROP_DOCSDIR, ftpresp->dir, 
  1819.             SA_MAX_NAME, &ftpresp->dirlen) != SA_SUCCEED)
  1820.         {
  1821. #ifdef    WIN32
  1822.             strcpy(ftpresp->dir, "c:/temp");
  1823. #else
  1824.             strcpy(ftpresp->dir, "/tmp");
  1825. #endif
  1826.             ftpresp->dirlen = strlen(ftpresp->dir);
  1827.         }
  1828.  
  1829.         if (sa_passwd_lookup(sactx, name, namelen, &passwd) == SA_SUCCEED)
  1830.             usepasswd = 1;
  1831.     }
  1832.     else if (sqlauth)
  1833.     {
  1834.         usepasswd = 1;
  1835.         if (sa_passwd_sqlauth(sactx, (SA_CONN *)NULL, name, namelen, password, 
  1836.             passwordlen, &passwd) != SA_SUCCEED)
  1837.         {
  1838.             sprintf(buffer, "SQL FTP login for user '%s' failed.", name);
  1839.             sa_log2(sactx, SA_LOG_WARN, buffer);
  1840.             return (SA_FAIL);
  1841.         }
  1842.     }
  1843.     else
  1844.     {
  1845.         usepasswd = 1;
  1846.         if (sa_passwd_lookup(sactx, name, namelen, &passwd) != SA_SUCCEED)
  1847.         {
  1848.             sprintf(buffer, "FTP login for user '%s' failed.", name);
  1849.             sa_log2(sactx, SA_LOG_WARN, buffer);
  1850.             return (SA_FAIL);
  1851.         }
  1852.  
  1853.         /* Verify the passwords are the same                            */
  1854.         if ((passwd.passwordlen != passwordlen) ||
  1855.             (strncmp(passwd.password, password, passwordlen) != 0))
  1856.         {
  1857.             /* Special case for anonymous user - NULL password match OK    */
  1858.             if ((namelen != 9) || (strncmp(name, "anonymous", 9) != 0))
  1859.             {
  1860.                 sprintf(buffer, 
  1861.                     "FTP login for user '%s' failed - bad password", name);
  1862.                 sa_log2(sactx, SA_LOG_WARN, buffer);
  1863.                 return (SA_FAIL);
  1864.             }
  1865.         }
  1866.     }
  1867.  
  1868.     if (usepasswd)
  1869.     {
  1870.         /* Return the directory and access priviledges                    */
  1871.         ftpresp->privs = passwd.privs;
  1872.         ftpresp->ftpmax = passwd.ftpmax;
  1873.  
  1874.         ftpresp->dirlen = passwd.dirlen;
  1875.         if (ftpresp->dirlen > 0)
  1876.             strncpy(ftpresp->dir, passwd.dir, ftpresp->dirlen);
  1877.         ftpresp->dir[ftpresp->dirlen] = '\0';
  1878.  
  1879.         ftpresp->grouplen = passwd.grouplen;
  1880.         if (ftpresp->grouplen > 0)
  1881.             strncpy(ftpresp->group, passwd.group, ftpresp->grouplen);
  1882.         ftpresp->group[ftpresp->grouplen] = '\0';
  1883.     }
  1884.  
  1885. #ifdef DEBUG
  1886.     sprintf(buffer, "%sFTP User '%s' logged in.", 
  1887.         (radiusauth ? "Radius " : (sqlauth ? "SQL " : (ntauth ? "NT " : ""))), 
  1888.         name);
  1889.     sa_log2(sactx, SA_LOG_TRACE, buffer);
  1890. #endif
  1891.  
  1892.     return (SA_SUCCEED);
  1893. }
  1894.  
  1895. /*
  1896. **  MAIL_CONNECT
  1897. **
  1898. **    Process an MAIL Connect request. Verify the username/password against 
  1899. **    the Sambar Server password interfaces.
  1900. **
  1901. **  Parameters:
  1902. **    sactx            Sambar Server Application context to release.
  1903. **    saconn            Sambar Server User Connection handle.
  1904. **    username        Name of the user logging in.
  1905. **    usernamelen        Length of the user name
  1906. **    password        Password of the user logging in.
  1907. **    passwordlen        Length of the password.
  1908. **
  1909. **  Return Values:
  1910. **    SA_SUCCESS         Login Accepted.
  1911. **    SA_FAIL            Login Denied.
  1912. */
  1913. SA_RETCODE SA_PUBLIC
  1914. mail_connect(sactx, name, namelen, password, passwordlen)
  1915. SA_CTX        *sactx;
  1916. SA_CHAR        *name;
  1917. SA_INT        namelen;
  1918. SA_CHAR        *password;
  1919. SA_INT        passwordlen;
  1920. {
  1921.     SA_BOOL        status;
  1922.     SA_CHAR        buffer[512];
  1923.  
  1924.     if ((sa_passwd_verify(sactx, name, namelen, password, passwordlen, &status) 
  1925.         != SA_SUCCEED) || (!status))
  1926.     {
  1927.         sprintf(buffer, 
  1928.             "MAIL login for user '%s' failed - bad password.", name);
  1929.         sa_log2(sactx, SA_LOG_WARN, buffer);
  1930.         return (SA_FAIL);
  1931.     }
  1932.  
  1933. #ifdef DEBUG
  1934.     sprintf(buffer, "MAIL User '%s' logged in.", name);
  1935.     sa_log2(sactx, SA_LOG_TRACE, buffer);
  1936. #endif
  1937.  
  1938.     return (SA_SUCCEED);
  1939. }
  1940.  
  1941. /*
  1942. **  TELNET_CONNECT
  1943. **
  1944. **    Process an Telnet Connect request. Verify the username/password against 
  1945. **    the Sambar Server password interfaces.
  1946. **
  1947. **  Parameters:
  1948. **    sactx            Sambar Server Application context to release.
  1949. **    saconn            Sambar Server User Connection handle.
  1950. **    username        Name of the user logging in.
  1951. **    usernamelen        Length of the user name
  1952. **    password        Password of the user logging in.
  1953. **    passwordlen        Length of the password.
  1954. **
  1955. **  Return Values:
  1956. **    SA_SUCCESS         Login Accepted.
  1957. **    SA_FAIL            Login Denied.
  1958. */
  1959. SA_RETCODE SA_PUBLIC
  1960. telnet_connect(sactx, name, namelen, password, passwordlen)
  1961. SA_CTX        *sactx;
  1962. SA_CHAR        *name;
  1963. SA_INT        namelen;
  1964. SA_CHAR        *password;
  1965. SA_INT        passwordlen;
  1966. {
  1967.     SA_BOOL        status;
  1968.     SA_CHAR        buffer[512];
  1969.  
  1970.     if ((sa_passwd_verify(sactx, name, namelen, password, passwordlen, &status) 
  1971.         != SA_SUCCEED) || (!status))
  1972.     {
  1973.         sprintf(buffer, 
  1974.             "Telnet login for user '%s' failed - bad password.", name);
  1975.         sa_log2(sactx, SA_LOG_WARN, buffer);
  1976.         return (SA_FAIL);
  1977.     }
  1978.  
  1979. #ifdef DEBUG
  1980.     sprintf(buffer, "Telnet User '%s' logged in.", name);
  1981.     sa_log2(sactx, SA_LOG_TRACE, buffer);
  1982. #endif
  1983.  
  1984.     return (SA_SUCCEED);
  1985. }
  1986.  
  1987. /*
  1988. **  GROUP_ADD
  1989. **
  1990. **    Add a new group
  1991. **
  1992. **  Parameters:
  1993. **    sactx        Sambar Server context
  1994. **    saconn        Sambar Server connection
  1995. **    saparams    RPC Parameters
  1996. **    infop        Error parameters
  1997. **
  1998. **  Returns:
  1999. **    SA_SUCCEED | SA_FAIL
  2000. */
  2001. SA_RETCODE SA_PUBLIC
  2002. group_add(sactx, saconn, saparams, infop)
  2003. SA_CTX        *sactx;
  2004. SA_CONN        *saconn;
  2005. SA_PARAMS    *saparams;
  2006. SA_INT        *infop;
  2007. {
  2008.     SA_CHAR        *data;
  2009.     SA_INT        datalen;
  2010.  
  2011.     if (sa_param(sactx, saparams, "groupname", &data, &datalen) != SA_SUCCEED)
  2012.     {
  2013.         *infop = SA_E_INVALIDDATA;
  2014.         sa_log2(sactx, SA_LOG_WARN, 
  2015.             "group_add(): Expected parameter 'groupname'!");
  2016.         return (SA_FAIL);
  2017.     }
  2018.     
  2019.     if ((datalen == 0) || (datalen > SA_MAX_NAME))
  2020.     {
  2021.         *infop = SA_E_INVALIDDATA;
  2022.         sa_log2(sactx, SA_LOG_WARN,
  2023.             "group_add(): 'name' field left NULL!");
  2024.         return (SA_FAIL);
  2025.     }
  2026.  
  2027.     /* Can't create the group "other"                                    */
  2028.     if ((datalen == 5) && 
  2029.         (memcmp(data, SA_DEFAULT_GROUP, strlen(SA_DEFAULT_GROUP)) == 0))
  2030.     {
  2031.         *infop = SA_E_INVALIDDATA;
  2032.         sa_log2(sactx, SA_LOG_WARN,
  2033.             "group_add(): 'other' group already exists!");
  2034.         return (SA_FAIL);
  2035.     }
  2036.  
  2037.     if (sa_group_add(sactx, data, datalen) != SA_SUCCEED)
  2038.     {
  2039.         *infop = SA_E_ALREADYDEFINED;
  2040.         sa_log2(sactx, SA_LOG_ERROR,
  2041.             "group_add(): sa_group_add() failed (already defined?)");
  2042.         return (SA_FAIL);
  2043.     }
  2044.  
  2045.     return (SA_SUCCEED);
  2046. }
  2047.  
  2048. /*
  2049. **  GROUP_DELETE
  2050. **
  2051. **    Delete an existing group
  2052. **
  2053. **  Parameters:
  2054. **    sactx        Sambar Server context
  2055. **    saconn        Sambar Server connection
  2056. **    saparams    RPC Parameters
  2057. **    infop        Error parameters
  2058. **
  2059. **  Returns:
  2060. **    SA_SUCCEED | SA_FAIL
  2061. **
  2062. **    Notes:
  2063. **    No users can belong to the group.
  2064. */
  2065. SA_RETCODE SA_PUBLIC
  2066. group_delete(sactx, saconn, saparams, infop)
  2067. SA_CTX        *sactx;
  2068. SA_CONN        *saconn;
  2069. SA_PARAMS    *saparams;
  2070. SA_INT        *infop;
  2071. {
  2072.     SA_INT        datalen;
  2073.     SA_CHAR        *data;
  2074.  
  2075.     if (sa_param(sactx, saparams, "groupname", &data, &datalen) != SA_SUCCEED)
  2076.     {
  2077.         *infop = SA_E_INVALIDDATA;
  2078.         sa_log2(sactx, SA_LOG_WARN,
  2079.             "group_delete(): Expected parameter 'groupname'!");
  2080.         return (SA_FAIL);
  2081.     }
  2082.  
  2083.     if ((datalen == 0) || (datalen > SA_MAX_NAME))
  2084.     {
  2085.         *infop = SA_E_INVALIDDATA;
  2086.         sa_log2(sactx, SA_LOG_WARN,
  2087.             "group_delete(): 'groupname' field left NULL!");
  2088.         return (SA_FAIL);
  2089.     }
  2090.  
  2091.     /* Can't delete the group "other"                                    */
  2092.     if ((datalen == 5) && 
  2093.         (memcmp(data, SA_DEFAULT_GROUP, strlen(SA_DEFAULT_GROUP)) == 0))
  2094.     {
  2095.         *infop = SA_E_INVALIDDATA;
  2096.         sa_log2(sactx, SA_LOG_WARN,
  2097.             "group_delete(): 'other' group cannot be deleted!");
  2098.         return (SA_FAIL);
  2099.     }
  2100.  
  2101.     /* Should only be allowed to do this if the group has no users.        */
  2102.     (SA_VOID)sa_group_delete(sactx, data, datalen);
  2103.  
  2104.     return (SA_SUCCEED);
  2105. }
  2106.  
  2107. /*
  2108. **  GROUP_SELECT
  2109. **
  2110. **    List all groups for selection.
  2111. **
  2112. **  Parameters:
  2113. **    sactx        Sambar Server context
  2114. **    saconn        Sambar Server connection
  2115. **    saparams    RPC Parameters
  2116. **    infop        Error parameters
  2117. **
  2118. **  Returns:
  2119. **    SA_SUCCEED | SA_FAIL
  2120. **
  2121. **  Notes:
  2122. **    This list is truncated at 100 names.
  2123. **    The group other always exists and is used for users with unrecognized
  2124. **    group names.
  2125. */
  2126. SA_RETCODE SA_PUBLIC
  2127. group_select(sactx, saconn, saparams, infop)
  2128. SA_CTX        *sactx;
  2129. SA_CONN        *saconn;
  2130. SA_PARAMS    *saparams;
  2131. SA_INT        *infop;
  2132. {
  2133.     SA_INT            i;
  2134.     SA_BOOL            found;
  2135.     SA_BOOL            selected;
  2136.     SA_INT            grouplen;
  2137.     SA_INT            userlen;
  2138.     SA_INT            numgroups;
  2139.     SA_CHAR            *user;
  2140.     SA_PASSWD        passwd;
  2141.     SA_CHAR            group[SA_MAX_NAME + 1];
  2142.     SA_GROUP        groups[100];
  2143.     SA_CHAR            buffer[512];
  2144.  
  2145.     /* If a name is provided make it SELECTED in the OPTION list        */
  2146.     userlen = 0;
  2147.     grouplen = 0;
  2148.     (SA_VOID)sa_param(sactx, saparams, "username", &user, &userlen);
  2149.  
  2150.     if ((userlen > 0) && (userlen < SA_MAX_NAME))
  2151.     {
  2152.         if (sa_passwd_lookup(sactx, user, userlen, &passwd) != SA_SUCCEED)
  2153.         {
  2154.             sprintf(buffer, "User lookup for '%s' failed.", user);
  2155.             sa_log2(sactx, SA_LOG_WARN, buffer);
  2156.             *infop = SA_E_INVALIDDATA;
  2157.             return (SA_FAIL);
  2158.         }
  2159.  
  2160.         grouplen = passwd.grouplen;
  2161.         if (grouplen > 0)
  2162.             memcpy(group, passwd.group, grouplen);
  2163.     }
  2164.  
  2165.     if (sa_group_list(sactx, groups, 100, &numgroups) != SA_SUCCEED)
  2166.     {
  2167.         sa_log2(sactx, SA_LOG_ERROR,
  2168.             "group_select(): failure retrieving groups list!");
  2169.         return (SA_FAIL);
  2170.     }
  2171.  
  2172.     /* We could sort the names alphabetically at this point...            */
  2173.  
  2174.     /* Display the list of groups.                                        */
  2175.     found = 0;
  2176.     for (i = 0; i < numgroups; i++)
  2177.     {
  2178.         selected = 0;
  2179.         if ((grouplen > 0) &&
  2180.             (groups[i].namelen == grouplen) &&
  2181.             (memcmp(group, groups[i].name, grouplen) == 0))
  2182.         {
  2183.             selected = 1;
  2184.             found = 1;
  2185.         }
  2186.  
  2187.         sprintf(buffer, "<OPTION %s>%s\n", (selected ? "SELECTED" : ""),
  2188.             groups[i].name);
  2189.  
  2190.         if (sa_conn_send(saconn, buffer, SA_NULLTERM) != SA_SUCCEED)
  2191.             return (SA_FAIL);
  2192.     }
  2193.  
  2194.     /* The group "other" always exists.                                    */
  2195.     sprintf(buffer, "<OPTION %s>%s\n", (found ? "" : "SELECTED"),
  2196.         SA_DEFAULT_GROUP);
  2197.     if (sa_conn_send(saconn, buffer, SA_NULLTERM) != SA_SUCCEED)
  2198.         return (SA_FAIL);
  2199.  
  2200.     return (SA_SUCCEED);
  2201. }
  2202.  
  2203. /*
  2204. **  GROUP_LIST
  2205. **
  2206. **    List all groups for delete.
  2207. **
  2208. **  Parameters:
  2209. **    sactx        Sambar Server context
  2210. **    saconn        Sambar Server connection
  2211. **    saparams    RPC Parameters
  2212. **    infop        Error parameters
  2213. **
  2214. **  Returns:
  2215. **    SA_SUCCEED | SA_FAIL
  2216. **
  2217. **  Notes:
  2218. **    This list is truncated at 100 names.
  2219. **    The group "other" always exists and is the default group.
  2220. */
  2221. SA_RETCODE SA_PUBLIC
  2222. group_list(sactx, saconn, saparams, infop)
  2223. SA_CTX        *sactx;
  2224. SA_CONN        *saconn;
  2225. SA_PARAMS    *saparams;
  2226. SA_INT        *infop;
  2227. {
  2228.     SA_INT            i;
  2229.     SA_INT            numgroups;
  2230.     SA_GROUP        groups[100];
  2231.     SA_CHAR            buffer[512];
  2232.  
  2233.     if (sa_group_list(sactx, groups, 100, &numgroups) != SA_SUCCEED)
  2234.     {
  2235.         sa_log2(sactx, SA_LOG_ERROR,
  2236.             "group_list(): failure retrieving groups list!");
  2237.         return (SA_FAIL);
  2238.     }
  2239.  
  2240.     /* We could sort the list alphabetically at this point.                */
  2241.  
  2242.     /* Display the list of groups.                                        */
  2243.     for (i = 0; i < numgroups; i++)
  2244.     {
  2245.         sprintf(buffer, 
  2246.             "<A TARGET=_top HREF=\"/session/delgroup?groupname=%s&RCpage=/sysadmin/usermgmt/users.htm\" onClick=\"return confirmDelete()\"><IMG border=0 HEIGHT=20 WIDTH=20 SRC=\"/sysimage/system/trash.gif\"></A> %s<BR>\n",
  2247.             groups[i].name, groups[i].name);
  2248.  
  2249.         if (sa_conn_send(saconn, buffer, SA_NULLTERM) != SA_SUCCEED)
  2250.             return (SA_FAIL);
  2251.     }
  2252.  
  2253.     return (SA_SUCCEED);
  2254. }
  2255.  
  2256. /*
  2257. **  USER__INLIST
  2258. **
  2259. **    Determine if the string is in the space separated list of values.
  2260. **
  2261. **  Parameters:
  2262. **    list        The space-spearated list to examine.
  2263. **    listlen        The length of the list.
  2264. **    value        The value to examine.
  2265. **    valuelen    The length of the value string.
  2266. **
  2267. **  Returns:
  2268. **    SA_TRUE | SA_FALSE
  2269. */
  2270. static SA_BOOL 
  2271. user__inlist(list, listlen, value, valuelen)
  2272. SA_CHAR        *list;
  2273. SA_INT        listlen;
  2274. SA_CHAR        *value;
  2275. SA_INT        valuelen;
  2276. {
  2277.     SA_INT        pos;
  2278.     SA_INT        head;
  2279.  
  2280.     if (listlen == SA_NULLTERM)
  2281.         listlen = strlen(list);
  2282.  
  2283.     if (valuelen == SA_NULLTERM)
  2284.         valuelen = strlen(value);
  2285.  
  2286.     if ((listlen == 0) || (valuelen == 0))
  2287.         return (0);
  2288.  
  2289.     /*
  2290.     ** See if the value is in the list.
  2291.     */
  2292.     pos = 0;
  2293.     while (pos < listlen)
  2294.     {
  2295.         if ((list[pos] != ' ') && (list[pos] != ','))
  2296.         {
  2297.             head = pos;
  2298.             while ((pos < listlen) && (list[pos] != ' ') && (list[pos] != ','))
  2299.                 pos++;
  2300.     
  2301.             if (pos - head != valuelen)
  2302.             {
  2303.                 pos++;
  2304.                 continue;
  2305.             }
  2306.  
  2307.             /*
  2308.             ** Determine if the index suffix matches
  2309.             */
  2310.             if (memcmp(&list[head], value, valuelen) == 0)
  2311.                 return (1);
  2312.         }
  2313.     
  2314.         pos++;
  2315.     }
  2316.  
  2317.     return (0);
  2318. }
  2319.