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