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