home *** CD-ROM | disk | FTP | other *** search
/ PC World 2001 August / PCWorld_2001-08_cd.bin / Komunikace / sambar / _setup.1 / login.c < prev    next >
C/C++ Source or Header  |  2001-04-02  |  50KB  |  1,972 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.     SA_VOID            *entry;
  411.     LOGIN_PROFILE    *profile;
  412. #ifdef DEBUG
  413.     SA_CHAR            buffer[512];
  414. #endif    /* DEBUG */
  415.  
  416.     /* Get the user's handle from the profile context                    */
  417.     if (sa_conn_key(saconn, SA_GET, LOGIN_PROFILE_KEY, (SA_VOID **)&profile)
  418.         != SA_SUCCEED)
  419.     {
  420.         /* User never completed login                                    */
  421.         return (SA_SUCCEED);
  422.     }
  423.  
  424.     /* Clear the user's profile handle                                    */
  425.     (SA_VOID)sa_conn_key(saconn, SA_CLEAR, LOGIN_PROFILE_KEY, &entry);
  426.  
  427. #ifdef DEBUG
  428.     sprintf(buffer, "User '%s' logged out.", profile->username);
  429.     sa_log(sactx, buffer);
  430. #endif    /* DEBUG */
  431.  
  432.     if (profile->data != (SA_PROFILE *)NULL)
  433.     {
  434.         (SA_VOID)sa_profile_save(sactx, profile->data);
  435.         (SA_VOID)sa_profile_exit(sactx, profile->data);
  436.     }
  437.  
  438.     (void)free(profile);
  439.  
  440.     return (SA_SUCCEED);
  441. }
  442.  
  443. /*
  444. **  USER_PROFILE
  445. **
  446. **    Respond to a user profile request.
  447. **
  448. **  Parameters:
  449. **    sactx        Sambar Server Application context to release.
  450. **    saconn        Sambar Server User Connection handle.
  451. **    buffer        Profile attribute being queried.
  452. **    buflen        Length of the profile attribute.
  453. **    data        Buffer for the profile result 
  454. **                Note: A maximum of 512 bytes may be written to the data buffer.
  455. **
  456. **  Return Values:
  457. **    SA_SUCCESS | SA_FAIL
  458. */
  459. SA_RETCODE SA_PUBLIC
  460. user_profile(sactx, saconn, action, name, namelen, datap)
  461. SA_CTX        *sactx;
  462. SA_CONN        *saconn;
  463. SA_INT        action;
  464. SA_CHAR        *name;
  465. SA_INT        namelen;
  466. SA_VOID        *datap;
  467. {
  468.     LOGIN_PROFILE    *profile;
  469.     SA_CHAR            tmp[512];
  470.  
  471.     /* Get the user's profile handle                                     */
  472.     if (sa_conn_key(saconn, SA_GET, LOGIN_PROFILE_KEY, (SA_VOID **)&profile)
  473.         != SA_SUCCEED)
  474.     {
  475.         /* User never completed login                                    */
  476.         return (SA_FAIL);
  477.     }
  478.  
  479.     if (profile == (LOGIN_PROFILE *)NULL)
  480.     {
  481.         sa_log(sactx, "user_profile:  LOGIN_PROFILE_KEY returned NULL!");
  482.         return (SA_FAIL);
  483.     }
  484.  
  485.     if (profile->data == (SA_PROFILE *)NULL)
  486.     {
  487.         sprintf(tmp, "user_profile:  SA_PROFILE returned NULL for user %s!",
  488.             profile->name);
  489.         sa_log(sactx, tmp);
  490.         return (SA_FAIL);
  491.     }
  492.  
  493.     /* 
  494.     ** Profile lookup
  495.     */
  496.     if (action == SA_GET)
  497.     {
  498.         if ((namelen == 5) && (strncmp(name, "group", 5) == 0))
  499.         {
  500.             *((SA_CHAR **)datap) = profile->group;
  501.         }
  502.         else if ((namelen == 4) && (strncmp(name, "name", 4) == 0))
  503.         {
  504.             *((SA_CHAR **)datap) = profile->name;
  505.         }
  506.         else if ((namelen == 8) && (strncmp(name, "username", 8) == 0))
  507.         {
  508.             *((SA_CHAR **)datap) = profile->username;
  509.         }
  510.         else if ((namelen == 3) && (strncmp(name, "dir", 3) == 0))
  511.         {
  512.             *((SA_CHAR **)datap) = profile->dir;
  513.         }
  514.         else
  515.         {
  516.             if (sa_profile_get(sactx, profile->data, name, namelen, 
  517.                 (SA_CHAR **)datap) != SA_SUCCEED)
  518.             {
  519. #ifdef    DEBUG
  520.                 sprintf(tmp, "Profile attribute '%s' not found!", name);
  521.                 sa_log(sactx, tmp);
  522. #endif    /* DEBUG */
  523.                 return (SA_FAIL);
  524.             }
  525.         }
  526.     }
  527.     else
  528.     {
  529.         if (sa_profile_set(sactx, profile->data, name, namelen, 
  530.             (SA_CHAR *)datap) != SA_SUCCEED)
  531.         {
  532.             sprintf(tmp, "Profile attribute '%s' could not be set!", name);
  533.             sa_log(sactx, tmp);
  534.             return (SA_FAIL);
  535.         }
  536.     }
  537.  
  538.     return (SA_SUCCEED);
  539. }
  540.  
  541. /*
  542. **  USER_ADD
  543. **
  544. **    Add a new user
  545. **
  546. **  Parameters:
  547. **    sactx        Sambar Server context
  548. **    saconn        Sambar Server connection
  549. **    saparams    RPC Parameters
  550. **    infop        Error parameters
  551. **
  552. **  Returns:
  553. **    SA_SUCCEED | SA_FAIL
  554. */
  555. SA_RETCODE SA_PUBLIC
  556. user_add(sactx, saconn, saparams, infop)
  557. SA_CTX        *sactx;
  558. SA_CONN        *saconn;
  559. SA_PARAMS    *saparams;
  560. SA_INT        *infop;
  561. {
  562.     SA_INT        mbox;
  563.     SA_INT        datalen;
  564.     SA_CHAR        *data;
  565.     SA_PASSWD    passwd;
  566.  
  567.     memset(&passwd, 0, sizeof(SA_PASSWD));
  568.     
  569.     mbox = 0;
  570.     if (sa_param(sactx, saparams, "mbox", &data, &datalen) == SA_SUCCEED)
  571.     {
  572.         if ((datalen == 2) && (stricmp(data, "on") == 0))
  573.             mbox = 1;
  574.     }
  575.     
  576.     if (sa_param(sactx, saparams, "password", &data, &datalen) != SA_SUCCEED)
  577.     {
  578.         *infop = SA_E_INVALIDDATA;
  579.         sa_log(sactx, "user_add(): Expected parameter 'password'!");
  580.         return (SA_FAIL);
  581.     }
  582.     
  583.     passwd.passwordlen = MIN(datalen, SA_MAX_NAME);
  584.     if (passwd.passwordlen > 0)
  585.         memcpy(passwd.password, data, passwd.passwordlen);
  586.  
  587.     if (sa_param(sactx, saparams, "group", &data, &datalen) != SA_SUCCEED)
  588.     {
  589.         *infop = SA_E_INVALIDDATA;
  590.         sa_log(sactx, "user_add(): Expected parameter 'group'!");
  591.         return (SA_FAIL);
  592.     }
  593.     
  594.     passwd.grouplen = MIN(datalen, SA_MAX_NAME);
  595.     if (passwd.grouplen > 0)
  596.         memcpy(passwd.group, data, passwd.grouplen);
  597.  
  598.     if (sa_param(sactx, saparams, "name", &data, &datalen) != SA_SUCCEED)
  599.     {
  600.         *infop = SA_E_INVALIDDATA;
  601.         sa_log(sactx, "user_add(): Expected parameter 'name'!");
  602.         return (SA_FAIL);
  603.     }
  604.     
  605.     passwd.namelen = MIN(datalen, SA_MAX_NAME);
  606.     if (passwd.namelen > 0)
  607.         memcpy(passwd.name, data, passwd.namelen);
  608.  
  609.     if (sa_param(sactx, saparams, "dir", &data, &datalen) != SA_SUCCEED)
  610.     {
  611.         *infop = SA_E_INVALIDDATA;
  612.         sa_log(sactx, "user_add(): Expected parameter 'dir'!");
  613.         return (SA_FAIL);
  614.     }
  615.     
  616.     passwd.dirlen = MIN(datalen, SA_MAX_NAME);
  617.     if (passwd.dirlen > 0)
  618.         memcpy(passwd.dir, data, passwd.dirlen);
  619.  
  620.     if (sa_param(sactx, saparams, "ftpprivs", &data, &datalen) != SA_SUCCEED)
  621.     {
  622.         *infop = SA_E_INVALIDDATA;
  623.         sa_log(sactx, "user_add(): Expected parameter 'ftpprivs'!");
  624.         return (SA_FAIL);
  625.     }
  626.  
  627.     if (datalen < 12)
  628.         passwd.privs = atol(data);
  629.     
  630.     if (sa_param(sactx, saparams, "ftpmax", &data, &datalen) != SA_SUCCEED)
  631.     {
  632.         *infop = SA_E_INVALIDDATA;
  633.         sa_log(sactx, "user_add(): Expected parameter 'ftpmax'!");
  634.         return (SA_FAIL);
  635.     }
  636.     
  637.     if (datalen < 12)
  638.         passwd.ftpmax = atol(data);
  639.     if (passwd.ftpmax < 5)
  640.         passwd.ftpmax = 0;
  641.  
  642.     if (sa_param(sactx, saparams, "username", &data, &datalen) != SA_SUCCEED)
  643.     {
  644.         *infop = SA_E_INVALIDDATA;
  645.         sa_log(sactx, "user_add(): Expected parameter 'username'!");
  646.         return (SA_FAIL);
  647.     }
  648.  
  649.     if ((datalen == 0) || (datalen > SA_MAX_NAME))
  650.     {
  651.         *infop = SA_E_INVALIDDATA;
  652.         sa_log(sactx, "user_add(): 'username' field left NULL!");
  653.         return (SA_FAIL);
  654.     }
  655.  
  656.     /* Create the user account.                                            */
  657.     if (sa_passwd_add(sactx, data, datalen, &passwd) != SA_SUCCEED)
  658.     {
  659.         *infop = SA_E_ALREADYDEFINED;
  660.         sa_log(sactx, "user_add(): sa_passwd_add() failed!");
  661.         return (SA_FAIL);
  662.     }
  663.  
  664.     /* Create the user mailbox.                                            */
  665.     if (mbox)
  666.     {
  667.         if (sa_mbox_create(sactx, data) != SA_SUCCEED)
  668.         {
  669.             *infop = SA_E_ALREADYDEFINED;
  670.             sa_log(sactx, "user_add(): sa_mbox_create() failed!");
  671.             return (SA_FAIL);
  672.         }
  673.     }
  674.  
  675.     return (SA_SUCCEED);
  676. }
  677.  
  678. /*
  679. **  USER_UPDATE
  680. **
  681. **    Update an existing user
  682. **
  683. **  Parameters:
  684. **    sactx        Sambar Server context
  685. **    saconn        Sambar Server connection
  686. **    saparams    RPC Parameters
  687. **    infop        Error parameters
  688. **
  689. **  Returns:
  690. **    SA_SUCCEED | SA_FAIL
  691. */
  692. SA_RETCODE SA_PUBLIC
  693. user_update(sactx, saconn, saparams, infop)
  694. SA_CTX        *sactx;
  695. SA_CONN        *saconn;
  696. SA_PARAMS    *saparams;
  697. SA_INT        *infop;
  698. {
  699.     SA_INT        mbox;
  700.     SA_INT        datalen;
  701.     SA_CHAR        *data;
  702.     SA_PASSWD    passwd;
  703.  
  704.     memset(&passwd, 0, sizeof(SA_PASSWD));
  705.  
  706.     mbox = 0;
  707.     if (sa_param(sactx, saparams, "mbox", &data, &datalen) == SA_SUCCEED)
  708.     {
  709.         if ((datalen == 2) && (stricmp(data, "on") == 0))
  710.             mbox = 1;
  711.     }
  712.     
  713.     if (sa_param(sactx, saparams, "password", &data, &datalen) != SA_SUCCEED)
  714.     {
  715.         *infop = SA_E_INVALIDDATA;
  716.         sa_log(sactx, "user_update(): Expected parameter 'password'!");
  717.         return (SA_FAIL);
  718.     }
  719.     
  720.     passwd.passwordlen = MIN(datalen, SA_MAX_NAME);
  721.     if (passwd.passwordlen > 0)
  722.         memcpy(passwd.password, data, passwd.passwordlen);
  723.  
  724.     if (sa_param(sactx, saparams, "group", &data, &datalen) != SA_SUCCEED)
  725.     {
  726.         *infop = SA_E_INVALIDDATA;
  727.         sa_log(sactx, "user_update(): Expected parameter 'group'!");
  728.         return (SA_FAIL);
  729.     }
  730.     
  731.     passwd.grouplen = MIN(datalen, SA_MAX_NAME);
  732.     if (passwd.grouplen > 0)
  733.         memcpy(passwd.group, data, passwd.grouplen);
  734.  
  735.     if (sa_param(sactx, saparams, "name", &data, &datalen) != SA_SUCCEED)
  736.     {
  737.         *infop = SA_E_INVALIDDATA;
  738.         sa_log(sactx, "user_update(): Expected parameter 'name'!");
  739.         return (SA_FAIL);
  740.     }
  741.     
  742.     passwd.namelen = MIN(datalen, SA_MAX_NAME);
  743.     if (passwd.namelen > 0)
  744.         memcpy(passwd.name, data, passwd.namelen);
  745.  
  746.     if (sa_param(sactx, saparams, "dir", &data, &datalen) != SA_SUCCEED)
  747.     {
  748.         *infop = SA_E_INVALIDDATA;
  749.         sa_log(sactx, "user_update(): Expected parameter 'dir'!");
  750.         return (SA_FAIL);
  751.     }
  752.     
  753.     passwd.dirlen = MIN(datalen, SA_MAX_NAME);
  754.     if (passwd.dirlen > 0)
  755.         memcpy(passwd.dir, data, passwd.dirlen);
  756.  
  757.     if (sa_param(sactx, saparams, "ftpprivs", &data, &datalen) != SA_SUCCEED)
  758.     {
  759.         *infop = SA_E_INVALIDDATA;
  760.         sa_log(sactx, "user_update(): Expected parameter 'ftpprivs'!");
  761.         return (SA_FAIL);
  762.     }
  763.     
  764.     if (datalen < 12)
  765.         passwd.privs = atol(data);
  766.  
  767.     if (sa_param(sactx, saparams, "ftpmax", &data, &datalen) != SA_SUCCEED)
  768.     {
  769.         *infop = SA_E_INVALIDDATA;
  770.         sa_log(sactx, "user_update(): Expected parameter 'ftpmax'!");
  771.         return (SA_FAIL);
  772.     }
  773.     
  774.     if (datalen < 12)
  775.         passwd.ftpmax = atol(data);
  776.     if (passwd.ftpmax < 5)
  777.         passwd.ftpmax = 0;
  778.  
  779.     if (sa_param(sactx, saparams, "username", &data, &datalen) != SA_SUCCEED)
  780.     {
  781.         *infop = SA_E_INVALIDDATA;
  782.         sa_log(sactx, "user_update(): Expected parameter 'username'!");
  783.         return (SA_FAIL);
  784.     }
  785.  
  786.     if ((datalen == 0) || (datalen > SA_MAX_NAME))
  787.     {
  788.         *infop = SA_E_INVALIDDATA;
  789.         sa_log(sactx, "user_update(): 'username' field left NULL!");
  790.         return (SA_FAIL);
  791.     }
  792.  
  793.     if (sa_passwd_update(sactx, data, datalen, &passwd) != SA_SUCCEED)
  794.     {
  795.         *infop = SA_E_ALREADYDEFINED;
  796.         sa_log(sactx, "user_update(): sa_passwd_update() failed!");
  797.         return (SA_FAIL);
  798.     }
  799.  
  800.     /* Create the user mailbox.                                            */
  801.     if (mbox)
  802.     {
  803.         if (sa_mbox_create(sactx, data) != SA_SUCCEED)
  804.         {
  805.             *infop = SA_E_ALREADYDEFINED;
  806.             sa_log(sactx, "user_update(): sa_mbox_create() failed!");
  807.             return (SA_FAIL);
  808.         }
  809.     }
  810.  
  811.     return (SA_SUCCEED);
  812. }
  813.  
  814. /*
  815. **  USER_DELETE
  816. **
  817. **    Delete an existing user
  818. **
  819. **  Parameters:
  820. **    sactx        Sambar Server context
  821. **    saconn        Sambar Server connection
  822. **    saparams    RPC Parameters
  823. **    infop        Error parameters
  824. **
  825. **  Returns:
  826. **    SA_SUCCEED | SA_FAIL
  827. */
  828. SA_RETCODE SA_PUBLIC
  829. user_delete(sactx, saconn, saparams, infop)
  830. SA_CTX        *sactx;
  831. SA_CONN        *saconn;
  832. SA_PARAMS    *saparams;
  833. SA_INT        *infop;
  834. {
  835.     SA_INT        datalen;
  836.     SA_INT        sysadminlen;
  837.     SA_CHAR        *data;
  838.     SA_CHAR        sysadmin[SA_MAX_NAME + 1];
  839.  
  840.     /* Get the sysadmin user (disallow deletes)                            */
  841.     if (sa_ctx_props(sactx, SA_GET, SA_CTXPROP_SYSADMIN, (SA_BYTE *)sysadmin,
  842.         SA_MAX_NAME, &sysadminlen) != SA_SUCCEED)
  843.     {
  844.         sa_log(sactx, "user_delete(): failure retrieving system admin user!");
  845.         return (SA_FAIL);
  846.     }
  847.  
  848.     if (sa_param(sactx, saparams, "username", &data, &datalen) != SA_SUCCEED)
  849.     {
  850.         *infop = SA_E_INVALIDDATA;
  851.         sa_log(sactx, "user_delete(): Expected parameter 'username'!");
  852.         return (SA_FAIL);
  853.     }
  854.  
  855.     if ((datalen == 0) || (datalen > SA_MAX_NAME))
  856.     {
  857.         *infop = SA_E_INVALIDDATA;
  858.         sa_log(sactx, "user_delete(): 'username' field left NULL!");
  859.         return (SA_FAIL);
  860.     }
  861.  
  862.     /* Don't allow the deletion of the system administrator                */
  863.     if ((datalen != sysadminlen) || (memcmp(sysadmin, data, sysadminlen) != 0))
  864.     {
  865.         (SA_VOID)sa_passwd_delete(sactx, data, datalen);
  866.         (SA_VOID)sa_mbox_delete(sactx, data);
  867.     }
  868.  
  869.     return (SA_SUCCEED);
  870. }
  871.  
  872. /*
  873. **  USER_SELECT
  874. **
  875. **    List all users for selection.
  876. **
  877. **  Parameters:
  878. **    sactx        Sambar Server context
  879. **    saconn        Sambar Server connection
  880. **    saparams    RPC Parameters
  881. **    infop        Error parameters
  882. **
  883. **  Returns:
  884. **    SA_SUCCEED | SA_FAIL
  885. **
  886. **  Notes:
  887. **    This list is truncated at 500 names.
  888. */
  889. SA_RETCODE SA_PUBLIC
  890. user_select(sactx, saconn, saparams, infop)
  891. SA_CTX        *sactx;
  892. SA_CONN        *saconn;
  893. SA_PARAMS    *saparams;
  894. SA_INT        *infop;
  895. {
  896.     SA_INT            i;
  897.     SA_BOOL            selected;
  898.     SA_INT            usernamelen;
  899.     SA_INT            numusers;
  900.     SA_CHAR            *username;
  901.     SA_USER            users[500];
  902.     SA_CHAR            buffer[512];
  903.  
  904.     /* If a username is provided make it SELECTED in the OPTION list    */
  905.     (SA_VOID)sa_param(sactx, saparams, "username", &username, &usernamelen);
  906.  
  907.     if (sa_passwd_list(sactx, users, 500, &numusers) != SA_SUCCEED)
  908.     {
  909.         sa_log(sactx, "user_select(): failure retrieving names list!");
  910.         return (SA_FAIL);
  911.     }
  912.  
  913.     /* We could sort the names alphabetically at this point...            */
  914.  
  915.     /* Display the list of users.                                        */
  916.     for (i = 0; i < numusers; i++)
  917.     {
  918.         selected = 0;
  919.         if ((users[i].usernamelen == usernamelen) &&
  920.             (memcmp(username, users[i].username, usernamelen) == 0))
  921.         {
  922.             selected = 1;
  923.         }
  924.  
  925.         sprintf(buffer, "<OPTION %s>%s\n", (selected ? "SELECTED" : ""),
  926.                 users[i].username);
  927.  
  928.         if (sa_conn_send(saconn, buffer, SA_NULLTERM) != SA_SUCCEED)
  929.             return (SA_FAIL);
  930.     }
  931.  
  932.     return (SA_SUCCEED);
  933. }
  934.  
  935. /*
  936. **  USER_LIST
  937. **
  938. **    List all users for delete or update.
  939. **
  940. **  Parameters:
  941. **    sactx        Sambar Server context
  942. **    saconn        Sambar Server connection
  943. **    saparams    RPC Parameters
  944. **    infop        Error parameters
  945. **
  946. **  Returns:
  947. **    SA_SUCCEED | SA_FAIL
  948. **
  949. **  Notes:
  950. **    This list is truncated at 500 names.
  951. **    List users by group...
  952. */
  953. SA_RETCODE SA_PUBLIC
  954. user_list(sactx, saconn, saparams, infop)
  955. SA_CTX        *sactx;
  956. SA_CONN        *saconn;
  957. SA_PARAMS    *saparams;
  958. SA_INT        *infop;
  959. {
  960.     SA_INT            i;
  961.     SA_INT            j;
  962.     SA_INT            sysadminlen;
  963.     SA_INT            numusers;
  964.     SA_INT            numgroups;
  965.     SA_GROUP        groups[100];
  966.     SA_USER            users[500];
  967.     SA_CHAR            sysadmin[SA_MAX_NAME + 1];
  968.     SA_CHAR            buffer[512];
  969.  
  970.     /* Get the sysadmin user (disallow deletes)                            */
  971.     if (sa_ctx_props(sactx, SA_GET, SA_CTXPROP_SYSADMIN, (SA_BYTE *)sysadmin,
  972.         SA_MAX_NAME, &sysadminlen) != SA_SUCCEED)
  973.     {
  974.         sa_log(sactx, "user_list(): failure retrieving system admin user!");
  975.         return (SA_FAIL);
  976.     }
  977.  
  978.     if (sa_passwd_list(sactx, users, 500, &numusers) != SA_SUCCEED)
  979.     {
  980.         sa_log(sactx, "user_list(): failure retrieving names list!");
  981.         return (SA_FAIL);
  982.     }
  983.  
  984.     if (sa_group_list(sactx, groups, 100, &numgroups) != SA_SUCCEED)
  985.     {
  986.         sa_log(sactx, "user_list(): failure retrieving groups list!");
  987.         return (SA_FAIL);
  988.     }
  989.  
  990.     /* We could sort the list alphabetically at this point.                */
  991.  
  992.     /*
  993.     ** Display the users by "group".
  994.     ** Zero the usernamelen after displaying so we can put the rest in
  995.     ** the "other" list.
  996.     */
  997.     for (j = 0; j < numgroups; j++)
  998.     {
  999.         sprintf(buffer, "<FONT SIZE=+1 COLOR=#990033>%s</FONT><BLOCKQUOTE>\n",
  1000.             groups[j].name);
  1001.         if (sa_conn_send(saconn, buffer, SA_NULLTERM) != SA_SUCCEED)
  1002.             return (SA_FAIL);
  1003.         
  1004.         /* Display the users in that group.                                */
  1005.         for (i = 0; i < numusers; i++)
  1006.         {
  1007.             if ((users[i].usernamelen > 0) && 
  1008.                 (users[i].grouplen == groups[j].namelen) &&
  1009.                 (memcmp(users[i].group, groups[j].name, users[i].grouplen)==0))
  1010.             {
  1011.                 /* Make sure we don't display the user twice.            */
  1012.                 users[i].usernamelen = 0;
  1013.  
  1014.                 if ((users[i].usernamelen != sysadminlen) ||
  1015.                     (strncmp(sysadmin, users[i].username, sysadminlen) != 0))
  1016.                 {
  1017.                     sprintf(buffer, 
  1018.                         "<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",
  1019.                         users[i].username);
  1020.  
  1021.                     if (sa_conn_send(saconn, buffer, SA_NULLTERM) != SA_SUCCEED)
  1022.                         return (SA_FAIL);
  1023.                 }
  1024.  
  1025.                 sprintf(buffer, 
  1026.                     "<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",
  1027.                     users[i].username, users[i].username);
  1028.  
  1029.                 if (sa_conn_send(saconn, buffer, SA_NULLTERM) != SA_SUCCEED)
  1030.                     return (SA_FAIL);
  1031.             }
  1032.         }
  1033.  
  1034.         if (sa_conn_send(saconn, "</BLOCKQUOTE>", SA_NULLTERM) != SA_SUCCEED)
  1035.             return (SA_FAIL);
  1036.     }
  1037.  
  1038.     /* Display the "other" group                                        */
  1039.     sprintf(buffer, "<FONT SIZE=+1 COLOR=#990066>%s</FONT><BLOCKQUOTE>\n", 
  1040.         SA_DEFAULT_GROUP);
  1041.     if (sa_conn_send(saconn, buffer, SA_NULLTERM) != SA_SUCCEED)
  1042.         return (SA_FAIL);
  1043.         
  1044.     /* Display the users in that group.                                    */
  1045.     for (i = 0; i < numusers; i++)
  1046.     {
  1047.         /* Display all users not in any other group.                    */
  1048.         if (users[i].usernamelen > 0)
  1049.         {
  1050.             if ((users[i].usernamelen != sysadminlen) ||
  1051.                 (strncmp(sysadmin, users[i].username, sysadminlen) != 0))
  1052.             {
  1053.                 sprintf(buffer, 
  1054.                     "<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",
  1055.                     users[i].username);
  1056.  
  1057.                 if (sa_conn_send(saconn, buffer, SA_NULLTERM) != SA_SUCCEED)
  1058.                     return (SA_FAIL);
  1059.             }
  1060.  
  1061.             sprintf(buffer, 
  1062.                 "<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",
  1063.                 users[i].username, users[i].username);
  1064.  
  1065.             if (sa_conn_send(saconn, buffer, SA_NULLTERM) != SA_SUCCEED)
  1066.                 return (SA_FAIL);
  1067.         }
  1068.  
  1069.     }
  1070.  
  1071.     if (sa_conn_send(saconn, "</BLOCKQUOTE>\n", SA_NULLTERM) != SA_SUCCEED)
  1072.         return (SA_FAIL);
  1073.  
  1074.     return (SA_SUCCEED);
  1075. }
  1076.  
  1077. /*
  1078. **  USER_PASSWD
  1079. **
  1080. **    Update a user' password.
  1081. **
  1082. **  Parameters:
  1083. **    sactx        Sambar Server context
  1084. **    saconn        Sambar Server connection
  1085. **    saparams    RPC Parameters
  1086. **    infop        Error parameters
  1087. **
  1088. **  Returns:
  1089. **    SA_SUCCEED | SA_FAIL
  1090. */
  1091. SA_RETCODE SA_PUBLIC
  1092. user_passwd(sactx, saconn, saparams, infop)
  1093. SA_CTX        *sactx;
  1094. SA_CONN        *saconn;
  1095. SA_PARAMS    *saparams;
  1096. SA_INT        *infop;
  1097. {
  1098.     SA_INT        datalen;
  1099.     SA_INT        passwordlen;
  1100.     SA_INT        usernamelen;
  1101.     SA_CHAR        *data;
  1102.     SA_CHAR        *password;
  1103.     SA_CHAR        *username;
  1104.     SA_PASSWD    passwd;
  1105.  
  1106.     /* What username is being updated?                                    */
  1107.     if (sa_param(sactx, saparams, "username", &username, &usernamelen) 
  1108.         != SA_SUCCEED)
  1109.     {
  1110.         *infop = SA_E_INVALIDDATA;
  1111.         sa_log(sactx, "user_passwd(): Expected parameter 'username'!");
  1112.         return (SA_FAIL);
  1113.     }
  1114.  
  1115.     if ((usernamelen == 0) || (usernamelen > SA_MAX_NAME))
  1116.     {
  1117.         *infop = SA_E_INVALIDDATA;
  1118.         sa_log(sactx, "user_update(): 'username' field left NULL!");
  1119.         return (SA_FAIL);
  1120.     }
  1121.  
  1122.     /* Lookup the username provided for update.                            */
  1123.     if (sa_passwd_lookup(sactx, username, usernamelen, &passwd) != SA_SUCCEED)
  1124.     {
  1125.         *infop = SA_E_INVALIDDATA;
  1126.         sa_log(sactx, "user_passwd(): sa_passwd_lookup() failed!");
  1127.         return (SA_FAIL);
  1128.     }
  1129.  
  1130.     /* Make sure that the password is valid.                        */
  1131.     if (sa_param(sactx, saparams, "password", &data, &datalen) != SA_SUCCEED)
  1132.     {
  1133.         *infop = SA_E_INVALIDDATA;
  1134.         sa_log(sactx, "user_passwd(): Expected parameter 'password'!");
  1135.         return (SA_FAIL);
  1136.     }
  1137.     
  1138.     /* Compare with the existing password.                            */
  1139.     if (datalen != passwd.passwordlen)
  1140.     {    
  1141.         *infop = SA_E_INVALIDDATA;
  1142.         sa_log(sactx, "user_passwd(): Invalid password provided.");
  1143.         return (SA_FAIL);
  1144.     }
  1145.     
  1146.     if (datalen > 0)
  1147.     {
  1148.         if (memcmp(passwd.password, data, datalen) != 0)
  1149.         {
  1150.             *infop = SA_E_INVALIDDATA;
  1151.             sa_log(sactx, "user_passwd(): Invalid password provided.");
  1152.             return (SA_FAIL);
  1153.         }
  1154.     }
  1155.  
  1156.     /* Get the new password.                                            */
  1157.     if (sa_param(sactx, saparams, "newpasswd", &password, &passwordlen) 
  1158.         != SA_SUCCEED)
  1159.     {
  1160.         *infop = SA_E_INVALIDDATA;
  1161.         sa_log(sactx, "user_passwd(): Expected parameter 'newpasswd'!");
  1162.         return (SA_FAIL);
  1163.     }
  1164.     
  1165.     /* Confirm the new password.                                        */
  1166.     if (sa_param(sactx, saparams, "confpasswd", &data, &datalen) 
  1167.         != SA_SUCCEED)
  1168.     {
  1169.         *infop = SA_E_INVALIDDATA;
  1170.         sa_log(sactx, "user_passwd(): Expected parameter 'confpasswd'!");
  1171.         return (SA_FAIL);
  1172.     }
  1173.  
  1174.     /* Does the new password and confirm password match?                */
  1175.     if ((passwordlen > 0) && (datalen > 0))
  1176.     {
  1177.         if ((passwordlen != datalen) ||
  1178.             (memcmp(password, data, datalen) != 0))
  1179.         {
  1180.             *infop = SA_E_INVALIDDATA;
  1181.             sa_log(sactx, 
  1182.                 "user_passwd(): New & confirmation password do not match!");
  1183.             return (SA_FAIL);
  1184.         }
  1185.     }
  1186.     
  1187.     passwd.passwordlen = MIN(datalen, SA_MAX_NAME);
  1188.     if (passwd.passwordlen > 0)
  1189.         memcpy(passwd.password, data, passwd.passwordlen);
  1190.  
  1191.     if (sa_passwd_update(sactx, username, usernamelen, &passwd) != SA_SUCCEED)
  1192.     {
  1193.         sa_log(sactx, "user_passwd(): sa_passwd_update() failed!");
  1194.         return (SA_FAIL);
  1195.     }
  1196.  
  1197.     return (SA_SUCCEED);
  1198. }
  1199.  
  1200. /*
  1201. **  USER_PROP
  1202. **
  1203. **    Lookup and return a single user property.
  1204. **
  1205. **  Parameters:
  1206. **    sactx        Sambar Server context
  1207. **    saconn        Sambar Server connection
  1208. **    saparams    RPC Parameters
  1209. **    infop        Error parameters
  1210. **
  1211. **  Return Values:
  1212. **    SA_SUCCESS | SA_FAIL
  1213. */
  1214. SA_RETCODE SA_PUBLIC
  1215. user_prop(sactx, saconn, saparams, infop)
  1216. SA_CTX        *sactx;
  1217. SA_CONN        *saconn;
  1218. SA_PARAMS    *saparams;
  1219. SA_INT        *infop;
  1220. {
  1221.     SA_PASSWD            passwd;
  1222.     SA_INT                userlen;
  1223.     SA_CHAR                *user;
  1224.     SA_INT                proplen;
  1225.     SA_CHAR                *prop;
  1226.     SA_CHAR                buffer[512];
  1227.  
  1228.     /* Get the page to direct to for user update                        */
  1229.     if (sa_param(sactx, saparams, "username", &user, &userlen) != SA_SUCCEED)
  1230.     {
  1231.         *infop = SA_E_INVALIDDATA;
  1232.         sa_log(sactx, "user_prop(): Expected parameter 'username'!");
  1233.         return (SA_FAIL);
  1234.     }
  1235.  
  1236.     if ((userlen == 0) || (userlen > SA_MAX_NAME))
  1237.     {
  1238.         *infop = SA_E_INVALIDDATA;
  1239.         sa_log(sactx, "user_prop(): 'username' field left NULL!");
  1240.         return (SA_FAIL);
  1241.     }
  1242.  
  1243.     /* Get the property being looked up.                                */
  1244.     if (sa_param(sactx, saparams, "prop", &prop, &proplen) != SA_SUCCEED)
  1245.     {
  1246.         *infop = SA_E_INVALIDDATA;
  1247.         sa_log(sactx, "user_prop(): Expected parameter 'prop'!");
  1248.         return (SA_FAIL);
  1249.     }
  1250.  
  1251.     if ((proplen == 0) || (proplen > SA_MAX_NAME))
  1252.     {
  1253.         *infop = SA_E_INVALIDDATA;
  1254.         sa_log(sactx, "user_prop(): 'prop' field left NULL!");
  1255.         return (SA_FAIL);
  1256.     }
  1257.  
  1258.     if (sa_passwd_lookup(sactx, user, userlen, &passwd) != SA_SUCCEED)
  1259.     {
  1260.         sprintf(buffer, "User lookup for '%s' failed.", user);
  1261.         sa_log(sactx, buffer);
  1262.         *infop = SA_E_INVALIDDATA;
  1263.         return (SA_FAIL);
  1264.     }
  1265.  
  1266.     /* Lookup and return the appropriate property                        */
  1267.     if (strcmp(prop, "group") == 0)
  1268.     {
  1269.         if (sa_conn_send(saconn, passwd.group, passwd.grouplen) != SA_SUCCEED)
  1270.             return (SA_FAIL);
  1271.     }
  1272.     else if (strcmp(prop, "password") == 0)
  1273.     {
  1274.         if (sa_conn_send(saconn, passwd.password, passwd.passwordlen) 
  1275.             != SA_SUCCEED)
  1276.         {
  1277.             return (SA_FAIL);
  1278.         }
  1279.     }
  1280.     else if (strcmp(prop, "name") == 0)
  1281.     {
  1282.         if (sa_conn_send(saconn, passwd.name, passwd.namelen) != SA_SUCCEED)
  1283.             return (SA_FAIL);
  1284.     }
  1285.     else if (strcmp(prop, "dir") == 0)
  1286.     {
  1287.         if (sa_conn_send(saconn, passwd.dir, passwd.dirlen) != SA_SUCCEED)
  1288.             return (SA_FAIL);
  1289.     }
  1290.     else if (strcmp(prop, "ftpprivs") == 0)
  1291.     {
  1292.         if (sa_param(sactx, saparams, "checked", &prop, &proplen) == SA_SUCCEED)
  1293.         {
  1294.             int        tmp;
  1295.  
  1296.             tmp = 0;
  1297.             if (proplen > 0)
  1298.                 tmp = atoi(prop);
  1299.         
  1300.             if (tmp == passwd.privs)
  1301.             {
  1302.                 if (sa_conn_send(saconn, "CHECKED", SA_NULLTERM) != SA_SUCCEED)
  1303.                     return (SA_FAIL);
  1304.             }
  1305.         }
  1306.         else
  1307.         {
  1308.             sprintf(buffer, "%ld", passwd.privs);
  1309.             if (sa_conn_send(saconn, buffer, SA_NULLTERM) != SA_SUCCEED)
  1310.                 return (SA_FAIL);
  1311.         }
  1312.     }
  1313.     else if (strcmp(prop, "ftpmax") == 0)
  1314.     {
  1315.         if (passwd.ftpmax < 5)
  1316.             passwd.ftpmax = 0;
  1317.         sprintf(buffer, "%ld", passwd.ftpmax);
  1318.         if (sa_conn_send(saconn, buffer, SA_NULLTERM) != SA_SUCCEED)
  1319.             return (SA_FAIL);
  1320.     }
  1321.     else if (strcmp(prop, "mbox") == 0)
  1322.     {
  1323.         if (sa_mbox_exists(sactx, user))
  1324.             strcpy(buffer, "CHECKED");
  1325.         else
  1326.             strcpy(buffer, "");
  1327.         if (sa_conn_send(saconn, buffer, SA_NULLTERM) != SA_SUCCEED)
  1328.             return (SA_FAIL);
  1329.     }
  1330.     else 
  1331.     {
  1332.         sprintf(buffer, "User lookup for property '%s' failed.", prop);
  1333.         sa_log(sactx, buffer);
  1334.         *infop = SA_E_INVALIDDATA;
  1335.         return (SA_FAIL);
  1336.     }
  1337.  
  1338.     return (SA_SUCCEED);
  1339. }
  1340.  
  1341. /*
  1342. **  USER_MAILLIST
  1343. **
  1344. **    List all mail users for delete or update.
  1345. **
  1346. **  Parameters:
  1347. **    sactx        Sambar Server context
  1348. **    saconn        Sambar Server connection
  1349. **    saparams    RPC Parameters
  1350. **    infop        Error parameters
  1351. **
  1352. **  Returns:
  1353. **    SA_SUCCEED | SA_FAIL
  1354. **
  1355. **  Notes:
  1356. **    This list is truncated at 500 names.
  1357. */
  1358. SA_RETCODE SA_PUBLIC
  1359. user_maillist(sactx, saconn, saparams, infop)
  1360. SA_CTX        *sactx;
  1361. SA_CONN        *saconn;
  1362. SA_PARAMS    *saparams;
  1363. SA_INT        *infop;
  1364. {
  1365.     SA_INT            i;
  1366.     SA_INT            numusers;
  1367.     SA_USER            users[500];
  1368.     SA_CHAR            buffer[512];
  1369.  
  1370.     if (sa_passwd_list(sactx, users, 500, &numusers) != SA_SUCCEED)
  1371.     {
  1372.         sa_log(sactx, "user_list(): failure retrieving names list!");
  1373.         return (SA_FAIL);
  1374.     }
  1375.  
  1376.     /* Sort the mail user list alphabetically at this point.            */
  1377.  
  1378.     if (sa_conn_send(saconn, "<TABLE BORDER=0 CELLPADDING=2>\n", SA_NULLTERM) 
  1379.         != SA_SUCCEED)
  1380.     {
  1381.         return (SA_FAIL);
  1382.     }
  1383.  
  1384.     if (sa_conn_send(saconn, 
  1385.         "<TR><TH>User</TH><TH align=center>Mailbox</TH><TH align=center>Digest</TH></TR>\n",
  1386.         SA_NULLTERM) != SA_SUCCEED)
  1387.     {
  1388.         return (SA_FAIL);
  1389.     }
  1390.  
  1391.     /*
  1392.     ** Display the mail users
  1393.     */
  1394.     for (i = 0; i < numusers; i++)
  1395.     {
  1396.         sprintf(buffer, "<TR><TD><b>%s</b> </TD><TD>", users[i].username);
  1397.         if (sa_conn_send(saconn, buffer, SA_NULLTERM) != SA_SUCCEED)
  1398.             return (SA_FAIL);
  1399.  
  1400.         if (sa_mbox_exists(sactx, users[i].username))
  1401.         {
  1402.             sprintf(buffer, 
  1403.                 "<A HREF=\"/session/usermbox?action=delete&username=%s&RCpage=/sysadmin/mail/users.stm\"><font color=#990000>Delete</font></A></TD><TD>",
  1404.                 users[i].username);
  1405.             if (sa_conn_send(saconn, buffer, SA_NULLTERM) != SA_SUCCEED)
  1406.                 return (SA_FAIL);
  1407.  
  1408.             sprintf(buffer, 
  1409.                 "<A HREF=\"/sysadmin/mail/digest.stm?username=%s\"><I>Generate</I></A>",
  1410.                 users[i].username);
  1411.             if (sa_conn_send(saconn, buffer, SA_NULLTERM) != SA_SUCCEED)
  1412.                 return (SA_FAIL);
  1413.         }
  1414.         else
  1415.         {
  1416.             sprintf(buffer, 
  1417.                 "<A HREF=\"/session/usermbox?action=create&username=%s&RCpage=/sysadmin/mail/users.stm\"><font color=#009900>Create</font></A></TD><TD>", 
  1418.                 users[i].username);
  1419.             if (sa_conn_send(saconn, buffer, SA_NULLTERM) != SA_SUCCEED)
  1420.                 return (SA_FAIL);
  1421.         }
  1422.  
  1423.         if (sa_conn_send(saconn, "</TD></TR>\n", SA_NULLTERM) != SA_SUCCEED)
  1424.             return (SA_FAIL);
  1425.     }
  1426.  
  1427.     if (sa_conn_send(saconn, "</TABLE>\n", SA_NULLTERM) != SA_SUCCEED)
  1428.         return (SA_FAIL);
  1429.  
  1430.     return (SA_SUCCEED);
  1431. }
  1432.  
  1433. /*
  1434. **  USER_MBOX
  1435. **
  1436. **    Update an user mailbox
  1437. **
  1438. **  Parameters:
  1439. **    sactx        Sambar Server context
  1440. **    saconn        Sambar Server connection
  1441. **    saparams    RPC Parameters
  1442. **    infop        Error parameters
  1443. **
  1444. **  Returns:
  1445. **    SA_SUCCEED | SA_FAIL
  1446. */
  1447. SA_RETCODE SA_PUBLIC
  1448. user_mailbox(sactx, saconn, saparams, infop)
  1449. SA_CTX        *sactx;
  1450. SA_CONN        *saconn;
  1451. SA_PARAMS    *saparams;
  1452. SA_INT        *infop;
  1453. {
  1454.     SA_BOOL        create;
  1455.     SA_INT        datalen;
  1456.     SA_CHAR        *data;
  1457.     SA_PASSWD    passwd;
  1458.  
  1459.     if (sa_param(sactx, saparams, "action", &data, &datalen) != SA_SUCCEED)
  1460.     {
  1461.         *infop = SA_E_INVALIDDATA;
  1462.         sa_log(sactx, "user_mailbox(): Expected parameter 'action'!");
  1463.         return (SA_FAIL);
  1464.     }
  1465.  
  1466.     if (stricmp(data, "create") == 0)
  1467.     {
  1468.         create = 1;
  1469.     }
  1470.     else if (stricmp(data, "delete") == 0)
  1471.     {
  1472.         create = 0;
  1473.     }
  1474.     else
  1475.     {
  1476.         *infop = SA_E_INVALIDDATA;
  1477.         sa_log(sactx, "user_mailbox(): Parameter 'action' not create/delete!");
  1478.         return (SA_FAIL);
  1479.     }
  1480.     
  1481.     if ((sa_param(sactx, saparams, "username", &data, &datalen) != SA_SUCCEED)
  1482.         || (datalen == 0) || (datalen > SA_MAX_NAME))
  1483.     {
  1484.         *infop = SA_E_INVALIDDATA;
  1485.         sa_log(sactx, "user_mailbox(): Expected parameter 'username'!");
  1486.         return (SA_FAIL);
  1487.     }
  1488.  
  1489.     /* Verify the user account exists.                                    */
  1490.     if (sa_passwd_lookup(sactx, data, datalen, &passwd) == SA_SUCCEED)
  1491.     {
  1492.         /* Create the user mailbox.                                        */
  1493.         if (create)
  1494.         {
  1495.             if (sa_mbox_create(sactx, data) != SA_SUCCEED)
  1496.                 sa_log(sactx, "user_mailbox(): sa_mbox_create() failed!");
  1497.         }
  1498.         else
  1499.         {
  1500.             if (sa_mbox_delete(sactx, data) != SA_SUCCEED)
  1501.                 sa_log(sactx, "user_mailbox(): sa_mbox_delete() failed!");
  1502.         }
  1503.     }
  1504.  
  1505.     return (SA_SUCCEED);
  1506. }
  1507.  
  1508.  
  1509. /*
  1510. **  FTP_CONNECT
  1511. **
  1512. **    Process an FTP Connect request. Verify the username/password against 
  1513. **    the Sambar Server password interfaces and return the root directory
  1514. **    and priviledges.
  1515. **
  1516. **  Parameters:
  1517. **    sactx            Sambar Server Application context to release.
  1518. **    saconn            Sambar Server User Connection handle.
  1519. **    username        Name of the user logging in.
  1520. **    usernamelen        Length of the user name
  1521. **    password        Password of the user logging in.
  1522. **    passwordlen        Length of the password.
  1523. **    ftpresp            FTP response structure.
  1524. **
  1525. **  Return Values:
  1526. **    SA_SUCCESS         Login Accepted.
  1527. **    SA_FAIL            Login Denied.
  1528. */
  1529. SA_RETCODE SA_PUBLIC
  1530. ftp_connect(sactx, name, namelen, password, passwordlen, ftpresp)
  1531. SA_CTX        *sactx;
  1532. SA_CHAR        *name;
  1533. SA_INT        namelen;
  1534. SA_CHAR        *password;
  1535. SA_INT        passwordlen;
  1536. SA_FTP        *ftpresp;
  1537. {
  1538.     SA_BOOL            ntauth;
  1539.     SA_BOOL            status;
  1540.     SA_PASSWD        passwd;
  1541.     SA_CHAR            buffer[512];
  1542.  
  1543.     ntauth = 0;
  1544.     if (sa_ctx_props(sactx, SA_GET, SA_CTXPROP_NTAUTH, buffer, 30, 
  1545.         (SA_INT *)NULL) == SA_SUCCEED)
  1546.     {
  1547.         if (stricmp(name, "true") == 0)
  1548.             ntauth = 1;
  1549.     }
  1550.  
  1551.     if (ntauth)
  1552.     {
  1553.         if ((sa_passwd_verify(sactx, name, namelen, password, passwordlen,
  1554.             &status) != SA_SUCCEED) || (!status))
  1555.         {
  1556.             sprintf(buffer, 
  1557.                 "FTP login for user '%s' failed - bad password (%s)", 
  1558.                 name, password);
  1559.             sa_log(sactx, buffer);
  1560.             return (SA_FAIL);
  1561.         }
  1562.  
  1563.         ftpresp->privs = SA_PRIV_READONLY;
  1564.         ftpresp->ftpmax = 0;
  1565.  
  1566.         if (sa_ctx_props(sactx, SA_GET, SA_CTXPROP_HOMEDIR, ftpresp->dir, 
  1567.             SA_MAX_NAME, &ftpresp->dirlen) != SA_SUCCEED)
  1568.         {
  1569. #ifdef    WIN32
  1570.             strcpy(ftpresp->dir, "c:/temp");
  1571. #else
  1572.             strcpy(ftpresp->dir, "/tmp");
  1573. #endif
  1574.             ftpresp->dirlen = strlen(ftpresp->dir);
  1575.         }
  1576.     }
  1577.     else
  1578.     {
  1579.         if (sa_passwd_lookup(sactx, name, namelen, &passwd) != SA_SUCCEED)
  1580.         {
  1581.             sprintf(buffer, "FTP login for user '%s' failed.", name);
  1582.             sa_log(sactx, buffer);
  1583.             return (SA_FAIL);
  1584.         }
  1585.  
  1586.         /* Verify the passwords are the same                            */
  1587.         if ((passwd.passwordlen != passwordlen) ||
  1588.             (strncmp(passwd.password, password, passwordlen) != 0))
  1589.         {
  1590.             /* Special case for anonymous user - NULL password match OK    */
  1591.             if ((namelen != 9) || (strncmp(name, "anonymous", 9) != 0))
  1592.             {
  1593.                 sprintf(buffer, 
  1594.                     "FTP login for user '%s' failed - bad password (%s)", 
  1595.                     name, password);
  1596.                 sa_log(sactx, buffer);
  1597.                 return (SA_FAIL);
  1598.             }
  1599.         }
  1600.  
  1601.         /* Return the directory and access priviledges                    */
  1602.         ftpresp->privs = passwd.privs;
  1603.         ftpresp->ftpmax = passwd.ftpmax;
  1604.         ftpresp->dirlen = passwd.dirlen;
  1605.         if (ftpresp->dirlen > 0)
  1606.             strncpy(ftpresp->dir, passwd.dir, ftpresp->dirlen);
  1607.  
  1608.         ftpresp->dir[ftpresp->dirlen] = '\0';
  1609.     }
  1610.  
  1611. #ifdef DEBUG
  1612.     sprintf(buffer, "FTP User '%s' logged in.", name);
  1613.     sa_log(sactx, buffer);
  1614. #endif    /* DEBUG */
  1615.  
  1616.     return (SA_SUCCEED);
  1617. }
  1618.  
  1619. /*
  1620. **  MAIL_CONNECT
  1621. **
  1622. **    Process an MAIL Connect request. Verify the username/password against 
  1623. **    the Sambar Server password interfaces.
  1624. **
  1625. **  Parameters:
  1626. **    sactx            Sambar Server Application context to release.
  1627. **    saconn            Sambar Server User Connection handle.
  1628. **    username        Name of the user logging in.
  1629. **    usernamelen        Length of the user name
  1630. **    password        Password of the user logging in.
  1631. **    passwordlen        Length of the password.
  1632. **
  1633. **  Return Values:
  1634. **    SA_SUCCESS         Login Accepted.
  1635. **    SA_FAIL            Login Denied.
  1636. */
  1637. SA_RETCODE SA_PUBLIC
  1638. mail_connect(sactx, name, namelen, password, passwordlen)
  1639. SA_CTX        *sactx;
  1640. SA_CHAR        *name;
  1641. SA_INT        namelen;
  1642. SA_CHAR        *password;
  1643. SA_INT        passwordlen;
  1644. {
  1645.     SA_BOOL        status;
  1646.     SA_CHAR        buffer[512];
  1647.  
  1648.     if ((sa_passwd_verify(sactx, name, namelen, password, passwordlen, &status) 
  1649.         != SA_SUCCEED) || (!status))
  1650.     {
  1651.         sprintf(buffer, 
  1652.             "MAIL login for user '%s' failed - bad password (%s).", 
  1653.             name, password);
  1654.         sa_log(sactx, buffer);
  1655.         return (SA_FAIL);
  1656.     }
  1657.  
  1658. #ifdef DEBUG
  1659.     sprintf(buffer, "MAIL User '%s' logged in.", name);
  1660.     sa_log(sactx, buffer);
  1661. #endif    /* DEBUG */
  1662.  
  1663.     return (SA_SUCCEED);
  1664. }
  1665.  
  1666. /*
  1667. **  TELNET_CONNECT
  1668. **
  1669. **    Process an Telnet Connect request. Verify the username/password against 
  1670. **    the Sambar Server password interfaces.
  1671. **
  1672. **  Parameters:
  1673. **    sactx            Sambar Server Application context to release.
  1674. **    saconn            Sambar Server User Connection handle.
  1675. **    username        Name of the user logging in.
  1676. **    usernamelen        Length of the user name
  1677. **    password        Password of the user logging in.
  1678. **    passwordlen        Length of the password.
  1679. **
  1680. **  Return Values:
  1681. **    SA_SUCCESS         Login Accepted.
  1682. **    SA_FAIL            Login Denied.
  1683. */
  1684. SA_RETCODE SA_PUBLIC
  1685. telnet_connect(sactx, name, namelen, password, passwordlen)
  1686. SA_CTX        *sactx;
  1687. SA_CHAR        *name;
  1688. SA_INT        namelen;
  1689. SA_CHAR        *password;
  1690. SA_INT        passwordlen;
  1691. {
  1692.     SA_BOOL        status;
  1693.     SA_CHAR        buffer[512];
  1694.  
  1695.     if ((sa_passwd_verify(sactx, name, namelen, password, passwordlen, &status) 
  1696.         != SA_SUCCEED) || (!status))
  1697.     {
  1698.         sprintf(buffer, 
  1699.             "Telnet login for user '%s' failed - bad password (%s).", 
  1700.             name, password);
  1701.         sa_log(sactx, buffer);
  1702.         return (SA_FAIL);
  1703.     }
  1704.  
  1705. #ifdef DEBUG
  1706.     sprintf(buffer, "Telnet User '%s' logged in.", name);
  1707.     sa_log(sactx, buffer);
  1708. #endif    /* DEBUG */
  1709.  
  1710.     return (SA_SUCCEED);
  1711. }
  1712.  
  1713. /*
  1714. **  GROUP_ADD
  1715. **
  1716. **    Add a new group
  1717. **
  1718. **  Parameters:
  1719. **    sactx        Sambar Server context
  1720. **    saconn        Sambar Server connection
  1721. **    saparams    RPC Parameters
  1722. **    infop        Error parameters
  1723. **
  1724. **  Returns:
  1725. **    SA_SUCCEED | SA_FAIL
  1726. */
  1727. SA_RETCODE SA_PUBLIC
  1728. group_add(sactx, saconn, saparams, infop)
  1729. SA_CTX        *sactx;
  1730. SA_CONN        *saconn;
  1731. SA_PARAMS    *saparams;
  1732. SA_INT        *infop;
  1733. {
  1734.     SA_CHAR        *data;
  1735.     SA_INT        datalen;
  1736.  
  1737.     if (sa_param(sactx, saparams, "groupname", &data, &datalen) != SA_SUCCEED)
  1738.     {
  1739.         *infop = SA_E_INVALIDDATA;
  1740.         sa_log(sactx, "group_add(): Expected parameter 'groupname'!");
  1741.         return (SA_FAIL);
  1742.     }
  1743.     
  1744.     if ((datalen == 0) || (datalen > SA_MAX_NAME))
  1745.     {
  1746.         *infop = SA_E_INVALIDDATA;
  1747.         sa_log(sactx, "group_add(): 'name' field left NULL!");
  1748.         return (SA_FAIL);
  1749.     }
  1750.  
  1751.     /* Can't create the group "other"                                    */
  1752.     if ((datalen == 5) && 
  1753.         (memcmp(data, SA_DEFAULT_GROUP, strlen(SA_DEFAULT_GROUP)) == 0))
  1754.     {
  1755.         *infop = SA_E_INVALIDDATA;
  1756.         sa_log(sactx, "group_add(): 'other' group already exists!");
  1757.         return (SA_FAIL);
  1758.     }
  1759.  
  1760.     if (sa_group_add(sactx, data, datalen) != SA_SUCCEED)
  1761.     {
  1762.         *infop = SA_E_ALREADYDEFINED;
  1763.         sa_log(sactx, "group_add(): sa_group_add() failed (already defined?)");
  1764.         return (SA_FAIL);
  1765.     }
  1766.  
  1767.     return (SA_SUCCEED);
  1768. }
  1769.  
  1770. /*
  1771. **  GROUP_DELETE
  1772. **
  1773. **    Delete an existing group
  1774. **
  1775. **  Parameters:
  1776. **    sactx        Sambar Server context
  1777. **    saconn        Sambar Server connection
  1778. **    saparams    RPC Parameters
  1779. **    infop        Error parameters
  1780. **
  1781. **  Returns:
  1782. **    SA_SUCCEED | SA_FAIL
  1783. **
  1784. **    Notes:
  1785. **    No users can belong to the group.
  1786. */
  1787. SA_RETCODE SA_PUBLIC
  1788. group_delete(sactx, saconn, saparams, infop)
  1789. SA_CTX        *sactx;
  1790. SA_CONN        *saconn;
  1791. SA_PARAMS    *saparams;
  1792. SA_INT        *infop;
  1793. {
  1794.     SA_INT        datalen;
  1795.     SA_CHAR        *data;
  1796.  
  1797.     if (sa_param(sactx, saparams, "groupname", &data, &datalen) != SA_SUCCEED)
  1798.     {
  1799.         *infop = SA_E_INVALIDDATA;
  1800.         sa_log(sactx, "group_delete(): Expected parameter 'groupname'!");
  1801.         return (SA_FAIL);
  1802.     }
  1803.  
  1804.     if ((datalen == 0) || (datalen > SA_MAX_NAME))
  1805.     {
  1806.         *infop = SA_E_INVALIDDATA;
  1807.         sa_log(sactx, "group_delete(): 'groupname' field left NULL!");
  1808.         return (SA_FAIL);
  1809.     }
  1810.  
  1811.     /* Can't delete the group "other"                                    */
  1812.     if ((datalen == 5) && 
  1813.         (memcmp(data, SA_DEFAULT_GROUP, strlen(SA_DEFAULT_GROUP)) == 0))
  1814.     {
  1815.         *infop = SA_E_INVALIDDATA;
  1816.         sa_log(sactx, "group_delete(): 'other' group cannot be deleted!");
  1817.         return (SA_FAIL);
  1818.     }
  1819.  
  1820.     /* Should only be allowed to do this if the group has no users.        */
  1821.     (SA_VOID)sa_group_delete(sactx, data, datalen);
  1822.  
  1823.     return (SA_SUCCEED);
  1824. }
  1825.  
  1826. /*
  1827. **  GROUP_SELECT
  1828. **
  1829. **    List all groups for selection.
  1830. **
  1831. **  Parameters:
  1832. **    sactx        Sambar Server context
  1833. **    saconn        Sambar Server connection
  1834. **    saparams    RPC Parameters
  1835. **    infop        Error parameters
  1836. **
  1837. **  Returns:
  1838. **    SA_SUCCEED | SA_FAIL
  1839. **
  1840. **  Notes:
  1841. **    This list is truncated at 100 names.
  1842. **    The group other always exists and is used for users with unrecognized
  1843. **    group names.
  1844. */
  1845. SA_RETCODE SA_PUBLIC
  1846. group_select(sactx, saconn, saparams, infop)
  1847. SA_CTX        *sactx;
  1848. SA_CONN        *saconn;
  1849. SA_PARAMS    *saparams;
  1850. SA_INT        *infop;
  1851. {
  1852.     SA_INT            i;
  1853.     SA_BOOL            found;
  1854.     SA_BOOL            selected;
  1855.     SA_INT            grouplen;
  1856.     SA_INT            userlen;
  1857.     SA_INT            numgroups;
  1858.     SA_CHAR            *user;
  1859.     SA_PASSWD        passwd;
  1860.     SA_CHAR            group[SA_MAX_NAME + 1];
  1861.     SA_GROUP        groups[100];
  1862.     SA_CHAR            buffer[512];
  1863.  
  1864.     /* If a name is provided make it SELECTED in the OPTION list        */
  1865.     userlen = 0;
  1866.     grouplen = 0;
  1867.     (SA_VOID)sa_param(sactx, saparams, "username", &user, &userlen);
  1868.  
  1869.     if ((userlen > 0) && (userlen < SA_MAX_NAME))
  1870.     {
  1871.         if (sa_passwd_lookup(sactx, user, userlen, &passwd) != SA_SUCCEED)
  1872.         {
  1873.             sprintf(buffer, "User lookup for '%s' failed.", user);
  1874.             sa_log(sactx, buffer);
  1875.             *infop = SA_E_INVALIDDATA;
  1876.             return (SA_FAIL);
  1877.         }
  1878.  
  1879.         grouplen = passwd.grouplen;
  1880.         if (grouplen > 0)
  1881.             memcpy(group, passwd.group, grouplen);
  1882.     }
  1883.  
  1884.     if (sa_group_list(sactx, groups, 100, &numgroups) != SA_SUCCEED)
  1885.     {
  1886.         sa_log(sactx, "group_select(): failure retrieving groups list!");
  1887.         return (SA_FAIL);
  1888.     }
  1889.  
  1890.     /* We could sort the names alphabetically at this point...            */
  1891.  
  1892.     /* Display the list of groups.                                        */
  1893.     found = 0;
  1894.     for (i = 0; i < numgroups; i++)
  1895.     {
  1896.         selected = 0;
  1897.         if ((grouplen > 0) &&
  1898.             (groups[i].namelen == grouplen) &&
  1899.             (memcmp(group, groups[i].name, grouplen) == 0))
  1900.         {
  1901.             selected = 1;
  1902.             found = 1;
  1903.         }
  1904.  
  1905.         sprintf(buffer, "<OPTION %s>%s\n", (selected ? "SELECTED" : ""),
  1906.             groups[i].name);
  1907.  
  1908.         if (sa_conn_send(saconn, buffer, SA_NULLTERM) != SA_SUCCEED)
  1909.             return (SA_FAIL);
  1910.     }
  1911.  
  1912.     /* The group "other" always exists.                                    */
  1913.     sprintf(buffer, "<OPTION %s>%s\n", (found ? "" : "SELECTED"),
  1914.         SA_DEFAULT_GROUP);
  1915.     if (sa_conn_send(saconn, buffer, SA_NULLTERM) != SA_SUCCEED)
  1916.         return (SA_FAIL);
  1917.  
  1918.     return (SA_SUCCEED);
  1919. }
  1920.  
  1921. /*
  1922. **  GROUP_LIST
  1923. **
  1924. **    List all groups for delete.
  1925. **
  1926. **  Parameters:
  1927. **    sactx        Sambar Server context
  1928. **    saconn        Sambar Server connection
  1929. **    saparams    RPC Parameters
  1930. **    infop        Error parameters
  1931. **
  1932. **  Returns:
  1933. **    SA_SUCCEED | SA_FAIL
  1934. **
  1935. **  Notes:
  1936. **    This list is truncated at 100 names.
  1937. **    The group "other" always exists and is the default group.
  1938. */
  1939. SA_RETCODE SA_PUBLIC
  1940. group_list(sactx, saconn, saparams, infop)
  1941. SA_CTX        *sactx;
  1942. SA_CONN        *saconn;
  1943. SA_PARAMS    *saparams;
  1944. SA_INT        *infop;
  1945. {
  1946.     SA_INT            i;
  1947.     SA_INT            numgroups;
  1948.     SA_GROUP        groups[100];
  1949.     SA_CHAR            buffer[512];
  1950.  
  1951.     if (sa_group_list(sactx, groups, 100, &numgroups) != SA_SUCCEED)
  1952.     {
  1953.         sa_log(sactx, "group_list(): failure retrieving groups list!");
  1954.         return (SA_FAIL);
  1955.     }
  1956.  
  1957.     /* We could sort the list alphabetically at this point.                */
  1958.  
  1959.     /* Display the list of groups.                                        */
  1960.     for (i = 0; i < numgroups; i++)
  1961.     {
  1962.         sprintf(buffer, 
  1963.             "<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",
  1964.             groups[i].name, groups[i].name);
  1965.  
  1966.         if (sa_conn_send(saconn, buffer, SA_NULLTERM) != SA_SUCCEED)
  1967.             return (SA_FAIL);
  1968.     }
  1969.  
  1970.     return (SA_SUCCEED);
  1971. }
  1972.