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