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