components/proftpd/mod_solaris_priv.c
branchs11-update
changeset 2711 4a08c47c8ec3
parent 881 b3186e256788
child 2205 af632779536e
child 3676 36119782570e
equal deleted inserted replaced
2710:3c5579720afc 2711:4a08c47c8ec3
     1 /*
     1 /*
     2  * ProFTPD - FTP server daemon
     2  * ProFTPD - FTP server daemon
     3  * Copyright (c) 1997, 1998 Public Flood Software
     3  * Copyright (c) 1997, 1998 Public Flood Software
     4  * Copyright (c) 2003-2010 The ProFTPD Project team
     4  * Copyright (c) 2003-2010 The ProFTPD Project team
     5  * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
     5  * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
     6  *
     6  *
     7  * This program is free software; you can redistribute it and/or modify
     7  * This program is free software; you can redistribute it and/or modify
     8  * it under the terms of the GNU General Public License as published by
     8  * it under the terms of the GNU General Public License as published by
     9  * the Free Software Foundation; either version 2 of the License, or
     9  * the Free Software Foundation; either version 2 of the License, or
    10  * (at your option) any later version.
    10  * (at your option) any later version.
   142 /* The POST_CMD handler for "PASS" is only called after PASS has
   142 /* The POST_CMD handler for "PASS" is only called after PASS has
   143  * successfully completed, which means authentication is successful,
   143  * successfully completed, which means authentication is successful,
   144  * so we can "tweak" our root access down to almost nothing.
   144  * so we can "tweak" our root access down to almost nothing.
   145  */
   145  */
   146 MODRET solaris_priv_post_pass(cmd_rec *cmd) {
   146 MODRET solaris_priv_post_pass(cmd_rec *cmd) {
   147   int res = 0;
   147   int res = -1;
   148   priv_set_t *p, *i;
   148   priv_set_t *p = NULL;
       
   149   priv_set_t *i = NULL;
   149 
   150 
   150   if (!use_privs)
   151   if (!use_privs)
   151     return PR_DECLINED(cmd);
   152     return PR_DECLINED(cmd);
   152 
   153 
   153   pr_signals_block();
   154   pr_signals_block();
   160    * We also remove the basic Solaris privileges we know we will
   161    * We also remove the basic Solaris privileges we know we will
   161    * never need.
   162    * never need.
   162    */
   163    */
   163 
   164 
   164   i = priv_allocset();
   165   i = priv_allocset();
       
   166   if (i == NULL)
       
   167     goto out;
   165   priv_basicset(i);
   168   priv_basicset(i);
   166   priv_delset(i, PRIV_PROC_EXEC);
   169   priv_delset(i, PRIV_PROC_EXEC);
   167   priv_delset(i, PRIV_PROC_FORK);
   170   priv_delset(i, PRIV_PROC_FORK);
   168   priv_delset(i, PRIV_PROC_INFO);
   171   priv_delset(i, PRIV_PROC_INFO);
   169   priv_delset(i, PRIV_PROC_SESSION);
   172   priv_delset(i, PRIV_PROC_SESSION);
   170   setppriv(PRIV_SET, PRIV_INHERITABLE, i);
   173   setppriv(PRIV_SET, PRIV_INHERITABLE, i);
   171 
   174 
   172   p = priv_allocset();
   175   p = priv_allocset();
       
   176   if (p == NULL)
       
   177     goto out;
   173   priv_basicset(p);
   178   priv_basicset(p);
   174 
   179 
   175   priv_addset(p, PRIV_NET_PRIVADDR);
   180   priv_addset(p, PRIV_NET_PRIVADDR);
   176   priv_addset(p, PRIV_PROC_AUDIT);
   181   priv_addset(p, PRIV_PROC_AUDIT);
   177 
   182 
   209   res = setppriv(PRIV_SET, PRIV_EFFECTIVE, p);
   214   res = setppriv(PRIV_SET, PRIV_EFFECTIVE, p);
   210 
   215 
   211   if (setreuid(session.uid, session.uid) == -1) {
   216   if (setreuid(session.uid, session.uid) == -1) {
   212     pr_log_pri(PR_LOG_ERR, MOD_SOLARIS_PRIV_VERSION ": setreuid: %s",
   217     pr_log_pri(PR_LOG_ERR, MOD_SOLARIS_PRIV_VERSION ": setreuid: %s",
   213 	strerror(errno));
   218 	strerror(errno));
       
   219     priv_freeset(i);
       
   220     priv_freeset(p);
   214     pr_signals_unblock();
   221     pr_signals_unblock();
   215     end_login(1);
   222     end_login(1);
   216   }
   223   }
       
   224 
       
   225 out:
       
   226   if (i != NULL)
       
   227     priv_freeset(i);
       
   228   if (p != NULL)
       
   229     priv_freeset(p);
       
   230 
   217   pr_signals_unblock();
   231   pr_signals_unblock();
   218 
   232 
   219   if (res != -1) {
   233   if (res != -1) {
   220     /* That's it!  Disable all further id switching */
   234     /* That's it!  Disable all further id switching */
   221     session.disable_id_switching = TRUE;
   235     session.disable_id_switching = TRUE;
   222 
   236 
   223   } else {
   237   } else {
   224     pr_log_pri(PR_LOG_NOTICE, MOD_SOLARIS_PRIV_VERSION ": attempt to configure "
   238     pr_log_pri(PR_LOG_NOTICE, MOD_SOLARIS_PRIV_VERSION ": attempt to configure "
   225       "privileges failed, reverting to normal operation");
   239       "privileges failed, reverting to normal operation");
   226   }
   240   }
       
   241 
       
   242   return PR_DECLINED(cmd);
       
   243 }
       
   244 
       
   245 static void log_err_permitted(const char* fn) {
       
   246   pr_log_pri(PR_LOG_ERR, MOD_SOLARIS_PRIV_VERSION ": %s(%s): %s",
       
   247     fn, "permitted", strerror(errno));
       
   248 }
       
   249 
       
   250 static void log_err_effective(const char* fn) {
       
   251   pr_log_pri(PR_LOG_ERR, MOD_SOLARIS_PRIV_VERSION ": %s(%s): %s",
       
   252     fn, "effective", strerror(errno));
       
   253 }
       
   254 
       
   255 MODRET solaris_priv_post_fail(cmd_rec *cmd) {
       
   256   priv_set_t* permitted_set = NULL;
       
   257   priv_set_t* effective_set = NULL;
       
   258 
       
   259   if ((permitted_set = priv_allocset()) == NULL) {
       
   260     log_err_permitted("priv_allocset");
       
   261     goto out;
       
   262   }
       
   263   if ((effective_set = priv_allocset()) == NULL) {
       
   264     log_err_effective("priv_allocset");
       
   265     goto out;
       
   266   }
       
   267 
       
   268   if (getppriv(PRIV_PERMITTED, permitted_set) != 0) {
       
   269     log_err_permitted("getppriv");
       
   270     goto out;
       
   271   }
       
   272   if (getppriv(PRIV_EFFECTIVE, effective_set) != 0) {
       
   273     log_err_effective("getppriv");
       
   274     goto out;
       
   275   }
       
   276 
       
   277   if (priv_addset(permitted_set, PRIV_PROC_AUDIT) != 0) {
       
   278     log_err_permitted("priv_addset");
       
   279     goto out;
       
   280   }
       
   281   if (priv_addset(effective_set, PRIV_PROC_AUDIT) != 0) {
       
   282     log_err_effective("priv_addset");
       
   283     goto out;
       
   284   }
       
   285 
       
   286   if (setppriv(PRIV_SET, PRIV_PERMITTED, permitted_set) != 0) {
       
   287     log_err_permitted("setppriv");
       
   288     goto out;
       
   289   }
       
   290   if (setppriv(PRIV_SET, PRIV_EFFECTIVE, effective_set) != 0) {
       
   291     log_err_effective("setppriv");
       
   292     goto out;
       
   293   }
       
   294 
       
   295 out:
       
   296   if (permitted_set != NULL)
       
   297     priv_freeset(permitted_set);
       
   298   if (effective_set != NULL)
       
   299     priv_freeset(effective_set);
   227 
   300 
   228   return PR_DECLINED(cmd);
   301   return PR_DECLINED(cmd);
   229 }
   302 }
   230 
   303 
   231 /* Initialization routines
   304 /* Initialization routines
   348   { NULL, NULL, NULL }
   421   { NULL, NULL, NULL }
   349 };
   422 };
   350 
   423 
   351 static cmdtable solaris_priv_cmdtab[] = {
   424 static cmdtable solaris_priv_cmdtab[] = {
   352   { POST_CMD, C_PASS, G_NONE, solaris_priv_post_pass, FALSE, FALSE },
   425   { POST_CMD, C_PASS, G_NONE, solaris_priv_post_pass, FALSE, FALSE },
       
   426   { POST_CMD_ERR, C_PASS, G_NONE, solaris_priv_post_fail, FALSE, FALSE },
   353   { 0, NULL }
   427   { 0, NULL }
   354 };
   428 };
   355 
   429 
   356 module solaris_priv_module = {
   430 module solaris_priv_module = {
   357   NULL, NULL,
   431   NULL, NULL,